Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/libjpeg-turbo/src/jdatasrc-tj.c
9904 views
1
/*
2
* jdatasrc-tj.c
3
*
4
* This file was part of the Independent JPEG Group's software:
5
* Copyright (C) 1994-1996, Thomas G. Lane.
6
* Modified 2009-2011 by Guido Vollbeding.
7
* libjpeg-turbo Modifications:
8
* Copyright (C) 2011, 2016, 2019, 2023, D. R. Commander.
9
* For conditions of distribution and use, see the accompanying README.ijg
10
* file.
11
*
12
* This file contains decompression data source routines for the case of
13
* reading JPEG data from memory or from a file (or any stdio stream).
14
* While these routines are sufficient for most applications,
15
* some will want to use a different source manager.
16
* IMPORTANT: we assume that fread() will correctly transcribe an array of
17
* JOCTETs from 8-bit-wide elements on external storage. If char is wider
18
* than 8 bits on your machine, you may need to do some tweaking.
19
*/
20
21
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
22
#include "jinclude.h"
23
#include "jpeglib.h"
24
#include "jerror.h"
25
26
void jpeg_mem_src_tj(j_decompress_ptr cinfo, const unsigned char *inbuffer,
27
size_t insize);
28
29
30
/*
31
* Initialize source --- called by jpeg_read_header
32
* before any data is actually read.
33
*/
34
35
METHODDEF(void)
36
init_mem_source(j_decompress_ptr cinfo)
37
{
38
/* no work necessary here */
39
}
40
41
42
/*
43
* Fill the input buffer --- called whenever buffer is emptied.
44
*
45
* In typical applications, this should read fresh data into the buffer
46
* (ignoring the current state of next_input_byte & bytes_in_buffer),
47
* reset the pointer & count to the start of the buffer, and return TRUE
48
* indicating that the buffer has been reloaded. It is not necessary to
49
* fill the buffer entirely, only to obtain at least one more byte.
50
*
51
* There is no such thing as an EOF return. If the end of the file has been
52
* reached, the routine has a choice of ERREXIT() or inserting fake data into
53
* the buffer. In most cases, generating a warning message and inserting a
54
* fake EOI marker is the best course of action --- this will allow the
55
* decompressor to output however much of the image is there. However,
56
* the resulting error message is misleading if the real problem is an empty
57
* input file, so we handle that case specially.
58
*
59
* In applications that need to be able to suspend compression due to input
60
* not being available yet, a FALSE return indicates that no more data can be
61
* obtained right now, but more may be forthcoming later. In this situation,
62
* the decompressor will return to its caller (with an indication of the
63
* number of scanlines it has read, if any). The application should resume
64
* decompression after it has loaded more data into the input buffer. Note
65
* that there are substantial restrictions on the use of suspension --- see
66
* the documentation.
67
*
68
* When suspending, the decompressor will back up to a convenient restart point
69
* (typically the start of the current MCU). next_input_byte & bytes_in_buffer
70
* indicate where the restart point will be if the current call returns FALSE.
71
* Data beyond this point must be rescanned after resumption, so move it to
72
* the front of the buffer rather than discarding it.
73
*/
74
75
METHODDEF(boolean)
76
fill_mem_input_buffer(j_decompress_ptr cinfo)
77
{
78
static const JOCTET mybuffer[4] = {
79
(JOCTET)0xFF, (JOCTET)JPEG_EOI, 0, 0
80
};
81
82
/* The whole JPEG data is expected to reside in the supplied memory
83
* buffer, so any request for more data beyond the given buffer size
84
* is treated as an error.
85
*/
86
WARNMS(cinfo, JWRN_JPEG_EOF);
87
88
/* Insert a fake EOI marker */
89
90
cinfo->src->next_input_byte = mybuffer;
91
cinfo->src->bytes_in_buffer = 2;
92
93
return TRUE;
94
}
95
96
97
/*
98
* Skip data --- used to skip over a potentially large amount of
99
* uninteresting data (such as an APPn marker).
100
*
101
* Writers of suspendable-input applications must note that skip_input_data
102
* is not granted the right to give a suspension return. If the skip extends
103
* beyond the data currently in the buffer, the buffer can be marked empty so
104
* that the next read will cause a fill_input_buffer call that can suspend.
105
* Arranging for additional bytes to be discarded before reloading the input
106
* buffer is the application writer's problem.
107
*/
108
109
METHODDEF(void)
110
skip_input_data(j_decompress_ptr cinfo, long num_bytes)
111
{
112
struct jpeg_source_mgr *src = cinfo->src;
113
114
/* Just a dumb implementation for now. Could use fseek() except
115
* it doesn't work on pipes. Not clear that being smart is worth
116
* any trouble anyway --- large skips are infrequent.
117
*/
118
if (num_bytes > 0) {
119
while (num_bytes > (long)src->bytes_in_buffer) {
120
num_bytes -= (long)src->bytes_in_buffer;
121
(void)(*src->fill_input_buffer) (cinfo);
122
/* note we assume that fill_input_buffer will never return FALSE,
123
* so suspension need not be handled.
124
*/
125
}
126
src->next_input_byte += (size_t)num_bytes;
127
src->bytes_in_buffer -= (size_t)num_bytes;
128
}
129
}
130
131
132
/*
133
* An additional method that can be provided by data source modules is the
134
* resync_to_restart method for error recovery in the presence of RST markers.
135
* For the moment, this source module just uses the default resync method
136
* provided by the JPEG library. That method assumes that no backtracking
137
* is possible.
138
*/
139
140
141
/*
142
* Terminate source --- called by jpeg_finish_decompress
143
* after all data has been read. Often a no-op.
144
*
145
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
146
* application must deal with any cleanup that should happen even
147
* for error exit.
148
*/
149
150
METHODDEF(void)
151
term_source(j_decompress_ptr cinfo)
152
{
153
/* no work necessary here */
154
}
155
156
157
/*
158
* Prepare for input from a supplied memory buffer.
159
* The buffer must contain the whole JPEG data.
160
*/
161
162
GLOBAL(void)
163
jpeg_mem_src_tj(j_decompress_ptr cinfo, const unsigned char *inbuffer,
164
size_t insize)
165
{
166
struct jpeg_source_mgr *src;
167
168
if (inbuffer == NULL || insize == 0) /* Treat empty input as fatal error */
169
ERREXIT(cinfo, JERR_INPUT_EMPTY);
170
171
/* The source object is made permanent so that a series of JPEG images
172
* can be read from the same buffer by calling jpeg_mem_src only before
173
* the first one.
174
*/
175
if (cinfo->src == NULL) { /* first time for this JPEG object? */
176
cinfo->src = (struct jpeg_source_mgr *)
177
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT,
178
sizeof(struct jpeg_source_mgr));
179
} else if (cinfo->src->init_source != init_mem_source) {
180
/* It is unsafe to reuse the existing source manager unless it was created
181
* by this function.
182
*/
183
ERREXIT(cinfo, JERR_BUFFER_SIZE);
184
}
185
186
src = cinfo->src;
187
src->init_source = init_mem_source;
188
src->fill_input_buffer = fill_mem_input_buffer;
189
src->skip_input_data = skip_input_data;
190
src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
191
src->term_source = term_source;
192
src->bytes_in_buffer = insize;
193
src->next_input_byte = (const JOCTET *)inbuffer;
194
}
195
196