]>
Commit | Line | Data |
---|---|---|
8414a40c | 1 | |
80ed523f VZ |
2 | /* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0 |
3 | specification is now totally obsolete and deprecated for new applications and | |
4 | images. This file was was created solely in order to read unconverted images | |
5 | still present on some users' computer systems. It will never be extended | |
6 | to write such files. Writing new-style JPEG compressed TIFFs is implemented | |
7 | in tif_jpeg.c. | |
8 | ||
9 | The code is carefully crafted to robustly read all gathered JPEG-in-TIFF | |
10 | testfiles, and anticipate as much as possible all other... But still, it may | |
11 | fail on some. If you encounter problems, please report them on the TIFF | |
12 | mailing list and/or to Joris Van Damme <info@awaresystems.be>. | |
13 | ||
14 | Please read the file called "TIFF Technical Note #2" if you need to be | |
15 | convinced this compression scheme is bad and breaks TIFF. That document | |
16 | is linked to from the LibTiff site <http://www.remotesensing.org/libtiff/> | |
17 | and from AWare Systems' TIFF section | |
18 | <http://www.awaresystems.be/imaging/tiff.html>. It is also absorbed | |
19 | in Adobe's specification supplements, marked "draft" up to this day, but | |
20 | supported by the TIFF community. | |
21 | ||
22 | This file interfaces with Release 6B of the JPEG Library written by the | |
23 | Independent JPEG Group. Previous versions of this file required a hack inside | |
24 | the LibJpeg library. This version no longer requires that. Remember to | |
25 | remove the hack if you update from the old version. | |
26 | ||
27 | Copyright (c) Joris Van Damme <info@awaresystems.be> | |
28 | Copyright (c) AWare Systems <http://www.awaresystems.be/> | |
29 | ||
30 | The licence agreement for this file is the same as the rest of the LibTiff | |
31 | library. | |
32 | ||
33 | IN NO EVENT SHALL JORIS VAN DAMME OR AWARE SYSTEMS BE LIABLE FOR | |
34 | ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, | |
35 | OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
36 | WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF | |
37 | LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |
38 | OF THIS SOFTWARE. | |
39 | ||
40 | Joris Van Damme and/or AWare Systems may be available for custom | |
41 | developement. If you like what you see, and need anything similar or related, | |
42 | contact <info@awaresystems.be>. | |
43 | */ | |
44 | ||
45 | /* What is what, and what is not? | |
46 | ||
47 | This decoder starts with an input stream, that is essentially the JpegInterchangeFormat | |
48 | stream, if any, followed by the strile data, if any. This stream is read in | |
49 | OJPEGReadByte and related functions. | |
50 | ||
51 | It analyzes the start of this stream, until it encounters non-marker data, i.e. | |
52 | compressed image data. Some of the header markers it sees have no actual content, | |
53 | like the SOI marker, and APP/COM markers that really shouldn't even be there. Some | |
54 | other markers do have content, and the valuable bits and pieces of information | |
55 | in these markers are saved, checking all to verify that the stream is more or | |
56 | less within expected bounds. This happens inside the OJPEGReadHeaderInfoSecStreamXxx | |
57 | functions. | |
58 | ||
59 | Some OJPEG imagery contains no valid JPEG header markers. This situation is picked | |
60 | up on if we've seen no SOF marker when we're at the start of the compressed image | |
61 | data. In this case, the tables are read from JpegXxxTables tags, and the other | |
62 | bits and pieces of information is initialized to its most basic value. This is | |
63 | implemented in the OJPEGReadHeaderInfoSecTablesXxx functions. | |
64 | ||
65 | When this is complete, a good and valid JPEG header can be assembled, and this is | |
66 | passed through to LibJpeg. When that's done, the remainder of the input stream, i.e. | |
67 | the compressed image data, can be passed through unchanged. This is done in | |
68 | OJPEGWriteStream functions. | |
69 | ||
70 | LibTiff rightly expects to know the subsampling values before decompression. Just like | |
71 | in new-style JPEG-in-TIFF, though, or even more so, actually, the YCbCrsubsampling | |
72 | tag is notoriously unreliable. To correct these tag values with the ones inside | |
73 | the JPEG stream, the first part of the input stream is pre-scanned in | |
74 | OJPEGSubsamplingCorrect, making no note of any other data, reporting no warnings | |
75 | or errors, up to the point where either these values are read, or it's clear they | |
76 | aren't there. This means that some of the data is read twice, but we feel speed | |
77 | in correcting these values is important enough to warrant this sacrifice. Allthough | |
78 | there is currently no define or other configuration mechanism to disable this behaviour, | |
79 | the actual header scanning is build to robustly respond with error report if it | |
80 | should encounter an uncorrected mismatch of subsampling values. See | |
81 | OJPEGReadHeaderInfoSecStreamSof. | |
82 | ||
83 | The restart interval and restart markers are the most tricky part... The restart | |
84 | interval can be specified in a tag. It can also be set inside the input JPEG stream. | |
85 | It can be used inside the input JPEG stream. If reading from strile data, we've | |
86 | consistenly discovered the need to insert restart markers in between the different | |
87 | striles, as is also probably the most likely interpretation of the original TIFF 6.0 | |
88 | specification. With all this setting of interval, and actual use of markers that is not | |
89 | predictable at the time of valid JPEG header assembly, the restart thing may turn | |
90 | out the Achilles heel of this implementation. Fortunately, most OJPEG writer vendors | |
91 | succeed in reading back what they write, which may be the reason why we've been able | |
92 | to discover ways that seem to work. | |
93 | ||
94 | Some special provision is made for planarconfig separate OJPEG files. These seem | |
95 | to consistently contain header info, a SOS marker, a plane, SOS marker, plane, SOS, | |
96 | and plane. This may or may not be a valid JPEG configuration, we don't know and don't | |
97 | care. We want LibTiff to be able to access the planes individually, without huge | |
98 | buffering inside LibJpeg, anyway. So we compose headers to feed to LibJpeg, in this | |
99 | case, that allow us to pass a single plane such that LibJpeg sees a valid | |
100 | single-channel JPEG stream. Locating subsequent SOS markers, and thus subsequent | |
101 | planes, is done inside OJPEGReadSecondarySos. | |
102 | ||
103 | The benefit of the scheme is... that it works, basically. We know of no other that | |
104 | does. It works without checking software tag, or otherwise going about things in an | |
105 | OJPEG flavor specific manner. Instead, it is a single scheme, that covers the cases | |
106 | with and without JpegInterchangeFormat, with and without striles, with part of | |
107 | the header in JpegInterchangeFormat and remainder in first strile, etc. It is forgiving | |
108 | and robust, may likely work with OJPEG flavors we've not seen yet, and makes most out | |
109 | of the data. | |
110 | ||
111 | Another nice side-effect is that a complete JPEG single valid stream is build if | |
112 | planarconfig is not separate (vast majority). We may one day use that to build | |
113 | converters to JPEG, and/or to new-style JPEG compression inside TIFF. | |
114 | ||
115 | A dissadvantage is the lack of random access to the individual striles. This is the | |
116 | reason for much of the complicated restart-and-position stuff inside OJPEGPreDecode. | |
117 | Applications would do well accessing all striles in order, as this will result in | |
118 | a single sequential scan of the input stream, and no restarting of LibJpeg decoding | |
119 | session. | |
120 | */ | |
121 | ||
122 | #define WIN32_LEAN_AND_MEAN | |
123 | #define VC_EXTRALEAN | |
124 | ||
8414a40c VZ |
125 | #include "tiffiop.h" |
126 | #ifdef OJPEG_SUPPORT | |
127 | ||
80ed523f VZ |
128 | /* Configuration defines here are: |
129 | * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some environments, | |
130 | * like eg LibTiffDelphi, this is not possible. For this reason, the actual calls to | |
131 | * libjpeg, with longjump stuff, are encapsulated in dedicated functions. When | |
132 | * JPEG_ENCAP_EXTERNAL is defined, these encapsulating functions are declared external | |
133 | * to this unit, and can be defined elsewhere to use stuff other then longjump. | |
134 | * The default mode, without JPEG_ENCAP_EXTERNAL, implements the call encapsulators | |
135 | * here, internally, with normal longjump. | |
136 | * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent is | |
137 | * conviniently available, but still it may be worthwhile to use _setjmp or sigsetjmp | |
138 | * in place of plain setjmp. These macros will make it easier. It is useless | |
139 | * to fiddle with these if you define JPEG_ENCAP_EXTERNAL. | |
140 | * OJPEG_BUFFER: Define the size of the desired buffer here. Should be small enough so as to guarantee | |
141 | * instant processing, optimal streaming and optimal use of processor cache, but also big | |
142 | * enough so as to not result in significant call overhead. It should be at least a few | |
143 | * bytes to accomodate some structures (this is verified in asserts), but it would not be | |
144 | * sensible to make it this small anyway, and it should be at most 64K since it is indexed | |
145 | * with uint16. We recommend 2K. | |
146 | * EGYPTIANWALK: You could also define EGYPTIANWALK here, but it is not used anywhere and has | |
147 | * absolutely no effect. That is why most people insist the EGYPTIANWALK is a bit silly. | |
148 | */ | |
149 | ||
150 | /* define LIBJPEG_ENCAP_EXTERNAL */ | |
151 | #define SETJMP(jbuf) setjmp(jbuf) | |
152 | #define LONGJMP(jbuf,code) longjmp(jbuf,code) | |
153 | #define JMP_BUF jmp_buf | |
154 | #define OJPEG_BUFFER 2048 | |
155 | /* define EGYPTIANWALK */ | |
156 | ||
157 | #define JPEG_MARKER_SOF0 0xC0 | |
158 | #define JPEG_MARKER_SOF1 0xC1 | |
159 | #define JPEG_MARKER_SOF3 0xC3 | |
160 | #define JPEG_MARKER_DHT 0xC4 | |
161 | #define JPEG_MARKER_RST0 0XD0 | |
162 | #define JPEG_MARKER_SOI 0xD8 | |
163 | #define JPEG_MARKER_EOI 0xD9 | |
164 | #define JPEG_MARKER_SOS 0xDA | |
165 | #define JPEG_MARKER_DQT 0xDB | |
166 | #define JPEG_MARKER_DRI 0xDD | |
167 | #define JPEG_MARKER_APP0 0xE0 | |
168 | #define JPEG_MARKER_COM 0xFE | |
169 | ||
170 | #define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC+0) | |
171 | #define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC+1) | |
172 | #define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC+2) | |
173 | #define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC+3) | |
174 | #define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC+4) | |
175 | #define FIELD_OJPEG_JPEGPROC (FIELD_CODEC+5) | |
176 | #define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC+6) | |
177 | ||
178 | static const TIFFField ojpegFields[] = { | |
179 | {TIFFTAG_JPEGIFOFFSET,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMAT,TRUE,FALSE,"JpegInterchangeFormat",NULL}, | |
180 | {TIFFTAG_JPEGIFBYTECOUNT,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH,TRUE,FALSE,"JpegInterchangeFormatLength",NULL}, | |
181 | {TIFFTAG_JPEGQTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGQTABLES,FALSE,TRUE,"JpegQTables",NULL}, | |
182 | {TIFFTAG_JPEGDCTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGDCTABLES,FALSE,TRUE,"JpegDcTables",NULL}, | |
183 | {TIFFTAG_JPEGACTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGACTABLES,FALSE,TRUE,"JpegAcTables",NULL}, | |
184 | {TIFFTAG_JPEGPROC,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGPROC,FALSE,FALSE,"JpegProc",NULL}, | |
185 | {TIFFTAG_JPEGRESTARTINTERVAL,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGRESTARTINTERVAL,FALSE,FALSE,"JpegRestartInterval",NULL}, | |
186 | }; | |
187 | ||
188 | #ifndef LIBJPEG_ENCAP_EXTERNAL | |
8414a40c | 189 | #include <setjmp.h> |
80ed523f VZ |
190 | #endif |
191 | ||
192 | /* We undefine FAR to avoid conflict with JPEG definition */ | |
193 | ||
8414a40c | 194 | #ifdef FAR |
80ed523f | 195 | #undef FAR |
8414a40c | 196 | #endif |
80ed523f VZ |
197 | |
198 | /* | |
199 | Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is | |
200 | not defined. Unfortunately, the MinGW and Borland compilers include | |
201 | a typedef for INT32, which causes a conflict. MSVC does not include | |
202 | a conficting typedef given the headers which are included. | |
203 | */ | |
204 | #if defined(__BORLANDC__) || defined(__MINGW32__) | |
205 | # define XMD_H 1 | |
206 | #endif | |
207 | ||
208 | /* Define "boolean" as unsigned char, not int, per Windows custom. */ | |
209 | #if defined(__WIN32__) && !defined(__MINGW32__) | |
210 | # ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ | |
211 | typedef unsigned char boolean; | |
212 | # endif | |
213 | # define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ | |
214 | #endif | |
215 | ||
8414a40c | 216 | #include "jpeglib.h" |
80ed523f | 217 | #include "jerror.h" |
8414a40c | 218 | |
94474c2e VZ |
219 | #ifndef HAVE_WXJPEG_BOOLEAN |
220 | typedef boolean wxjpeg_boolean; | |
221 | #endif | |
222 | ||
80ed523f VZ |
223 | typedef struct jpeg_error_mgr jpeg_error_mgr; |
224 | typedef struct jpeg_common_struct jpeg_common_struct; | |
225 | typedef struct jpeg_decompress_struct jpeg_decompress_struct; | |
226 | typedef struct jpeg_source_mgr jpeg_source_mgr; | |
8414a40c | 227 | |
80ed523f VZ |
228 | typedef enum { |
229 | osibsNotSetYet, | |
230 | osibsJpegInterchangeFormat, | |
231 | osibsStrile, | |
232 | osibsEof | |
233 | } OJPEGStateInBufferSource; | |
234 | ||
235 | typedef enum { | |
236 | ososSoi, | |
237 | ososQTable0,ososQTable1,ososQTable2,ososQTable3, | |
238 | ososDcTable0,ososDcTable1,ososDcTable2,ososDcTable3, | |
239 | ososAcTable0,ososAcTable1,ososAcTable2,ososAcTable3, | |
240 | ososDri, | |
241 | ososSof, | |
242 | ososSos, | |
243 | ososCompressed, | |
244 | ososRst, | |
245 | ososEoi | |
246 | } OJPEGStateOutState; | |
247 | ||
248 | typedef struct { | |
249 | TIFF* tif; | |
250 | #ifndef LIBJPEG_ENCAP_EXTERNAL | |
251 | JMP_BUF exit_jmpbuf; | |
252 | #endif | |
253 | TIFFVGetMethod vgetparent; | |
254 | TIFFVSetMethod vsetparent; | |
255 | TIFFPrintMethod printdir; | |
256 | uint64 file_size; | |
257 | uint32 image_width; | |
258 | uint32 image_length; | |
259 | uint32 strile_width; | |
260 | uint32 strile_length; | |
261 | uint32 strile_length_total; | |
262 | uint8 samples_per_pixel; | |
263 | uint8 plane_sample_offset; | |
264 | uint8 samples_per_pixel_per_plane; | |
265 | uint64 jpeg_interchange_format; | |
266 | uint64 jpeg_interchange_format_length; | |
267 | uint8 jpeg_proc; | |
268 | uint8 subsamplingcorrect; | |
269 | uint8 subsamplingcorrect_done; | |
270 | uint8 subsampling_tag; | |
271 | uint8 subsampling_hor; | |
272 | uint8 subsampling_ver; | |
273 | uint8 subsampling_force_desubsampling_inside_decompression; | |
274 | uint8 qtable_offset_count; | |
275 | uint8 dctable_offset_count; | |
276 | uint8 actable_offset_count; | |
277 | uint64 qtable_offset[3]; | |
278 | uint64 dctable_offset[3]; | |
279 | uint64 actable_offset[3]; | |
280 | uint8* qtable[4]; | |
281 | uint8* dctable[4]; | |
282 | uint8* actable[4]; | |
283 | uint16 restart_interval; | |
284 | uint8 restart_index; | |
285 | uint8 sof_log; | |
286 | uint8 sof_marker_id; | |
287 | uint32 sof_x; | |
288 | uint32 sof_y; | |
289 | uint8 sof_c[3]; | |
290 | uint8 sof_hv[3]; | |
291 | uint8 sof_tq[3]; | |
292 | uint8 sos_cs[3]; | |
293 | uint8 sos_tda[3]; | |
294 | struct { | |
295 | uint8 log; | |
296 | OJPEGStateInBufferSource in_buffer_source; | |
297 | uint32 in_buffer_next_strile; | |
298 | uint64 in_buffer_file_pos; | |
299 | uint64 in_buffer_file_togo; | |
300 | } sos_end[3]; | |
301 | uint8 readheader_done; | |
302 | uint8 writeheader_done; | |
303 | uint16 write_cursample; | |
304 | uint32 write_curstrile; | |
305 | uint8 libjpeg_session_active; | |
306 | uint8 libjpeg_jpeg_query_style; | |
307 | jpeg_error_mgr libjpeg_jpeg_error_mgr; | |
308 | jpeg_decompress_struct libjpeg_jpeg_decompress_struct; | |
309 | jpeg_source_mgr libjpeg_jpeg_source_mgr; | |
310 | uint8 subsampling_convert_log; | |
311 | uint32 subsampling_convert_ylinelen; | |
312 | uint32 subsampling_convert_ylines; | |
313 | uint32 subsampling_convert_clinelen; | |
314 | uint32 subsampling_convert_clines; | |
315 | uint32 subsampling_convert_ybuflen; | |
316 | uint32 subsampling_convert_cbuflen; | |
317 | uint32 subsampling_convert_ycbcrbuflen; | |
318 | uint8* subsampling_convert_ycbcrbuf; | |
319 | uint8* subsampling_convert_ybuf; | |
320 | uint8* subsampling_convert_cbbuf; | |
321 | uint8* subsampling_convert_crbuf; | |
322 | uint32 subsampling_convert_ycbcrimagelen; | |
323 | uint8** subsampling_convert_ycbcrimage; | |
324 | uint32 subsampling_convert_clinelenout; | |
325 | uint32 subsampling_convert_state; | |
326 | uint32 bytes_per_line; /* if the codec outputs subsampled data, a 'line' in bytes_per_line */ | |
327 | uint32 lines_per_strile; /* and lines_per_strile means subsampling_ver desubsampled rows */ | |
328 | OJPEGStateInBufferSource in_buffer_source; | |
329 | uint32 in_buffer_next_strile; | |
330 | uint32 in_buffer_strile_count; | |
331 | uint64 in_buffer_file_pos; | |
332 | uint8 in_buffer_file_pos_log; | |
333 | uint64 in_buffer_file_togo; | |
334 | uint16 in_buffer_togo; | |
335 | uint8* in_buffer_cur; | |
336 | uint8 in_buffer[OJPEG_BUFFER]; | |
337 | OJPEGStateOutState out_state; | |
338 | uint8 out_buffer[OJPEG_BUFFER]; | |
339 | uint8* skip_buffer; | |
340 | } OJPEGState; | |
341 | ||
342 | static int OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap); | |
343 | static int OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap); | |
344 | static void OJPEGPrintDir(TIFF* tif, FILE* fd, long flags); | |
345 | ||
346 | static int OJPEGFixupTags(TIFF* tif); | |
347 | static int OJPEGSetupDecode(TIFF* tif); | |
348 | static int OJPEGPreDecode(TIFF* tif, uint16 s); | |
349 | static int OJPEGPreDecodeSkipRaw(TIFF* tif); | |
350 | static int OJPEGPreDecodeSkipScanlines(TIFF* tif); | |
351 | static int OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); | |
352 | static int OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc); | |
353 | static int OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc); | |
354 | static void OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc); | |
355 | static int OJPEGSetupEncode(TIFF* tif); | |
356 | static int OJPEGPreEncode(TIFF* tif, uint16 s); | |
357 | static int OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s); | |
358 | static int OJPEGPostEncode(TIFF* tif); | |
359 | static void OJPEGCleanup(TIFF* tif); | |
360 | ||
361 | static void OJPEGSubsamplingCorrect(TIFF* tif); | |
362 | static int OJPEGReadHeaderInfo(TIFF* tif); | |
363 | static int OJPEGReadSecondarySos(TIFF* tif, uint16 s); | |
364 | static int OJPEGWriteHeaderInfo(TIFF* tif); | |
365 | static void OJPEGLibjpegSessionAbort(TIFF* tif); | |
366 | ||
367 | static int OJPEGReadHeaderInfoSec(TIFF* tif); | |
368 | static int OJPEGReadHeaderInfoSecStreamDri(TIFF* tif); | |
369 | static int OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif); | |
370 | static int OJPEGReadHeaderInfoSecStreamDht(TIFF* tif); | |
371 | static int OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id); | |
372 | static int OJPEGReadHeaderInfoSecStreamSos(TIFF* tif); | |
373 | static int OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif); | |
374 | static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif); | |
375 | static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif); | |
376 | ||
377 | static int OJPEGReadBufferFill(OJPEGState* sp); | |
378 | static int OJPEGReadByte(OJPEGState* sp, uint8* byte); | |
379 | static int OJPEGReadBytePeek(OJPEGState* sp, uint8* byte); | |
380 | static void OJPEGReadByteAdvance(OJPEGState* sp); | |
381 | static int OJPEGReadWord(OJPEGState* sp, uint16* word); | |
382 | static int OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem); | |
383 | static void OJPEGReadSkip(OJPEGState* sp, uint16 len); | |
384 | ||
385 | static int OJPEGWriteStream(TIFF* tif, void** mem, uint32* len); | |
386 | static void OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len); | |
387 | static void OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len); | |
388 | static void OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len); | |
389 | static void OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len); | |
390 | static void OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len); | |
391 | static void OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len); | |
392 | static void OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len); | |
393 | static int OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len); | |
394 | static void OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len); | |
395 | static void OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len); | |
396 | ||
397 | #ifdef LIBJPEG_ENCAP_EXTERNAL | |
398 | extern int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo); | |
399 | extern int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image); | |
400 | extern int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo); | |
401 | extern int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines); | |
402 | extern int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines); | |
403 | extern void jpeg_encap_unwind(TIFF* tif); | |
404 | #else | |
405 | static int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* j); | |
406 | static int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image); | |
407 | static int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo); | |
408 | static int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines); | |
409 | static int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines); | |
410 | static void jpeg_encap_unwind(TIFF* tif); | |
411 | #endif | |
8414a40c | 412 | |
80ed523f VZ |
413 | static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo); |
414 | static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo); | |
415 | static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo); | |
94474c2e | 416 | static wxjpeg_boolean OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo); |
80ed523f | 417 | static void OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes); |
94474c2e | 418 | static wxjpeg_boolean OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired); |
80ed523f | 419 | static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo); |
8414a40c | 420 | |
80ed523f VZ |
421 | int |
422 | TIFFInitOJPEG(TIFF* tif, int scheme) | |
423 | { | |
424 | static const char module[]="TIFFInitOJPEG"; | |
425 | OJPEGState* sp; | |
426 | ||
427 | assert(scheme==COMPRESSION_OJPEG); | |
428 | ||
429 | /* | |
430 | * Merge codec-specific tag information. | |
431 | */ | |
432 | if (!_TIFFMergeFields(tif, ojpegFields, TIFFArrayCount(ojpegFields))) { | |
433 | TIFFErrorExt(tif->tif_clientdata, module, | |
434 | "Merging Old JPEG codec-specific tags failed"); | |
435 | return 0; | |
436 | } | |
8414a40c | 437 | |
80ed523f VZ |
438 | /* state block */ |
439 | sp=_TIFFmalloc(sizeof(OJPEGState)); | |
440 | if (sp==NULL) | |
441 | { | |
442 | TIFFErrorExt(tif->tif_clientdata,module,"No space for OJPEG state block"); | |
443 | return(0); | |
444 | } | |
445 | _TIFFmemset(sp,0,sizeof(OJPEGState)); | |
446 | sp->tif=tif; | |
447 | sp->jpeg_proc=1; | |
448 | sp->subsampling_hor=2; | |
449 | sp->subsampling_ver=2; | |
450 | TIFFSetField(tif,TIFFTAG_YCBCRSUBSAMPLING,2,2); | |
451 | /* tif codec methods */ | |
452 | tif->tif_fixuptags=OJPEGFixupTags; | |
453 | tif->tif_setupdecode=OJPEGSetupDecode; | |
454 | tif->tif_predecode=OJPEGPreDecode; | |
455 | tif->tif_postdecode=OJPEGPostDecode; | |
456 | tif->tif_decoderow=OJPEGDecode; | |
457 | tif->tif_decodestrip=OJPEGDecode; | |
458 | tif->tif_decodetile=OJPEGDecode; | |
459 | tif->tif_setupencode=OJPEGSetupEncode; | |
460 | tif->tif_preencode=OJPEGPreEncode; | |
461 | tif->tif_postencode=OJPEGPostEncode; | |
462 | tif->tif_encoderow=OJPEGEncode; | |
463 | tif->tif_encodestrip=OJPEGEncode; | |
464 | tif->tif_encodetile=OJPEGEncode; | |
465 | tif->tif_cleanup=OJPEGCleanup; | |
466 | tif->tif_data=(uint8*)sp; | |
467 | /* tif tag methods */ | |
468 | sp->vgetparent=tif->tif_tagmethods.vgetfield; | |
469 | tif->tif_tagmethods.vgetfield=OJPEGVGetField; | |
470 | sp->vsetparent=tif->tif_tagmethods.vsetfield; | |
471 | tif->tif_tagmethods.vsetfield=OJPEGVSetField; | |
472 | sp->printdir=tif->tif_tagmethods.printdir; | |
473 | tif->tif_tagmethods.printdir=OJPEGPrintDir; | |
474 | /* Some OJPEG files don't have strip or tile offsets or bytecounts tags. | |
475 | Some others do, but have totally meaningless or corrupt values | |
476 | in these tags. In these cases, the JpegInterchangeFormat stream is | |
477 | reliable. In any case, this decoder reads the compressed data itself, | |
478 | from the most reliable locations, and we need to notify encapsulating | |
479 | LibTiff not to read raw strips or tiles for us. */ | |
480 | tif->tif_flags|=TIFF_NOREADRAW; | |
481 | return(1); | |
482 | } | |
8414a40c | 483 | |
80ed523f VZ |
484 | static int |
485 | OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap) | |
486 | { | |
487 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
488 | switch(tag) | |
489 | { | |
490 | case TIFFTAG_JPEGIFOFFSET: | |
491 | *va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format; | |
492 | break; | |
493 | case TIFFTAG_JPEGIFBYTECOUNT: | |
494 | *va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format_length; | |
495 | break; | |
496 | case TIFFTAG_YCBCRSUBSAMPLING: | |
497 | if (sp->subsamplingcorrect_done==0) | |
498 | OJPEGSubsamplingCorrect(tif); | |
499 | *va_arg(ap,uint16*)=(uint16)sp->subsampling_hor; | |
500 | *va_arg(ap,uint16*)=(uint16)sp->subsampling_ver; | |
501 | break; | |
502 | case TIFFTAG_JPEGQTABLES: | |
503 | *va_arg(ap,uint32*)=(uint32)sp->qtable_offset_count; | |
504 | *va_arg(ap,void**)=(void*)sp->qtable_offset; | |
505 | break; | |
506 | case TIFFTAG_JPEGDCTABLES: | |
507 | *va_arg(ap,uint32*)=(uint32)sp->dctable_offset_count; | |
508 | *va_arg(ap,void**)=(void*)sp->dctable_offset; | |
509 | break; | |
510 | case TIFFTAG_JPEGACTABLES: | |
511 | *va_arg(ap,uint32*)=(uint32)sp->actable_offset_count; | |
512 | *va_arg(ap,void**)=(void*)sp->actable_offset; | |
513 | break; | |
514 | case TIFFTAG_JPEGPROC: | |
515 | *va_arg(ap,uint16*)=(uint16)sp->jpeg_proc; | |
516 | break; | |
517 | case TIFFTAG_JPEGRESTARTINTERVAL: | |
518 | *va_arg(ap,uint16*)=sp->restart_interval; | |
519 | break; | |
520 | default: | |
521 | return (*sp->vgetparent)(tif,tag,ap); | |
522 | } | |
523 | return (1); | |
524 | } | |
8414a40c | 525 | |
80ed523f VZ |
526 | static int |
527 | OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap) | |
8414a40c | 528 | { |
80ed523f VZ |
529 | static const char module[]="OJPEGVSetField"; |
530 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
531 | uint32 ma; | |
532 | uint64* mb; | |
533 | uint32 n; | |
534 | switch(tag) | |
535 | { | |
536 | case TIFFTAG_JPEGIFOFFSET: | |
537 | sp->jpeg_interchange_format=(uint64)va_arg(ap,uint64); | |
538 | break; | |
539 | case TIFFTAG_JPEGIFBYTECOUNT: | |
540 | sp->jpeg_interchange_format_length=(uint64)va_arg(ap,uint64); | |
541 | break; | |
542 | case TIFFTAG_YCBCRSUBSAMPLING: | |
543 | sp->subsampling_tag=1; | |
544 | sp->subsampling_hor=(uint8)va_arg(ap,uint16_vap); | |
545 | sp->subsampling_ver=(uint8)va_arg(ap,uint16_vap); | |
546 | tif->tif_dir.td_ycbcrsubsampling[0]=sp->subsampling_hor; | |
547 | tif->tif_dir.td_ycbcrsubsampling[1]=sp->subsampling_ver; | |
548 | break; | |
549 | case TIFFTAG_JPEGQTABLES: | |
550 | ma=(uint32)va_arg(ap,uint32); | |
551 | if (ma!=0) | |
552 | { | |
553 | if (ma>3) | |
554 | { | |
555 | TIFFErrorExt(tif->tif_clientdata,module,"JpegQTables tag has incorrect count"); | |
556 | return(0); | |
557 | } | |
558 | sp->qtable_offset_count=(uint8)ma; | |
559 | mb=(uint64*)va_arg(ap,uint64*); | |
560 | for (n=0; n<ma; n++) | |
561 | sp->qtable_offset[n]=mb[n]; | |
562 | } | |
563 | break; | |
564 | case TIFFTAG_JPEGDCTABLES: | |
565 | ma=(uint32)va_arg(ap,uint32); | |
566 | if (ma!=0) | |
567 | { | |
568 | if (ma>3) | |
569 | { | |
570 | TIFFErrorExt(tif->tif_clientdata,module,"JpegDcTables tag has incorrect count"); | |
571 | return(0); | |
572 | } | |
573 | sp->dctable_offset_count=(uint8)ma; | |
574 | mb=(uint64*)va_arg(ap,uint64*); | |
575 | for (n=0; n<ma; n++) | |
576 | sp->dctable_offset[n]=mb[n]; | |
577 | } | |
578 | break; | |
579 | case TIFFTAG_JPEGACTABLES: | |
580 | ma=(uint32)va_arg(ap,uint32); | |
581 | if (ma!=0) | |
582 | { | |
583 | if (ma>3) | |
584 | { | |
585 | TIFFErrorExt(tif->tif_clientdata,module,"JpegAcTables tag has incorrect count"); | |
586 | return(0); | |
587 | } | |
588 | sp->actable_offset_count=(uint8)ma; | |
589 | mb=(uint64*)va_arg(ap,uint64*); | |
590 | for (n=0; n<ma; n++) | |
591 | sp->actable_offset[n]=mb[n]; | |
592 | } | |
593 | break; | |
594 | case TIFFTAG_JPEGPROC: | |
595 | sp->jpeg_proc=(uint8)va_arg(ap,uint16_vap); | |
596 | break; | |
597 | case TIFFTAG_JPEGRESTARTINTERVAL: | |
598 | sp->restart_interval=(uint16)va_arg(ap,uint16_vap); | |
599 | break; | |
600 | default: | |
601 | return (*sp->vsetparent)(tif,tag,ap); | |
602 | } | |
603 | TIFFSetFieldBit(tif,TIFFFieldWithTag(tif,tag)->field_bit); | |
604 | tif->tif_flags|=TIFF_DIRTYDIRECT; | |
605 | return(1); | |
8414a40c VZ |
606 | } |
607 | ||
608 | static void | |
80ed523f VZ |
609 | OJPEGPrintDir(TIFF* tif, FILE* fd, long flags) |
610 | { | |
611 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
612 | uint8 m; | |
613 | (void)flags; | |
614 | assert(sp!=NULL); | |
615 | if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMAT)) | |
616 | fprintf(fd," JpegInterchangeFormat: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format); | |
617 | if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH)) | |
618 | fprintf(fd," JpegInterchangeFormatLength: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format_length); | |
619 | if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGQTABLES)) | |
620 | { | |
621 | fprintf(fd," JpegQTables:"); | |
622 | for (m=0; m<sp->qtable_offset_count; m++) | |
623 | fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->qtable_offset[m]); | |
624 | fprintf(fd,"\n"); | |
625 | } | |
626 | if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGDCTABLES)) | |
627 | { | |
628 | fprintf(fd," JpegDcTables:"); | |
629 | for (m=0; m<sp->dctable_offset_count; m++) | |
630 | fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->dctable_offset[m]); | |
631 | fprintf(fd,"\n"); | |
632 | } | |
633 | if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGACTABLES)) | |
634 | { | |
635 | fprintf(fd," JpegAcTables:"); | |
636 | for (m=0; m<sp->actable_offset_count; m++) | |
637 | fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->actable_offset[m]); | |
638 | fprintf(fd,"\n"); | |
639 | } | |
640 | if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGPROC)) | |
641 | fprintf(fd," JpegProc: %u\n",(unsigned int)sp->jpeg_proc); | |
642 | if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGRESTARTINTERVAL)) | |
643 | fprintf(fd," JpegRestartInterval: %u\n",(unsigned int)sp->restart_interval); | |
644 | if (sp->printdir) | |
645 | (*sp->printdir)(tif, fd, flags); | |
646 | } | |
8414a40c | 647 | |
80ed523f VZ |
648 | static int |
649 | OJPEGFixupTags(TIFF* tif) | |
650 | { | |
651 | (void) tif; | |
652 | return(1); | |
653 | } | |
8414a40c | 654 | |
80ed523f VZ |
655 | static int |
656 | OJPEGSetupDecode(TIFF* tif) | |
657 | { | |
658 | static const char module[]="OJPEGSetupDecode"; | |
659 | TIFFWarningExt(tif->tif_clientdata,module,"Depreciated and troublesome old-style JPEG compression mode, please convert to new-style JPEG compression and notify vendor of writing software"); | |
660 | return(1); | |
661 | } | |
8414a40c VZ |
662 | |
663 | static int | |
80ed523f VZ |
664 | OJPEGPreDecode(TIFF* tif, uint16 s) |
665 | { | |
666 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
667 | uint32 m; | |
668 | if (sp->subsamplingcorrect_done==0) | |
669 | OJPEGSubsamplingCorrect(tif); | |
670 | if (sp->readheader_done==0) | |
671 | { | |
672 | if (OJPEGReadHeaderInfo(tif)==0) | |
673 | return(0); | |
674 | } | |
675 | if (sp->sos_end[s].log==0) | |
676 | { | |
677 | if (OJPEGReadSecondarySos(tif,s)==0) | |
678 | return(0); | |
679 | } | |
680 | if isTiled(tif) | |
681 | m=tif->tif_curtile; | |
682 | else | |
683 | m=tif->tif_curstrip; | |
684 | if ((sp->writeheader_done!=0) && ((sp->write_cursample!=s) || (sp->write_curstrile>m))) | |
685 | { | |
686 | if (sp->libjpeg_session_active!=0) | |
687 | OJPEGLibjpegSessionAbort(tif); | |
688 | sp->writeheader_done=0; | |
689 | } | |
690 | if (sp->writeheader_done==0) | |
691 | { | |
692 | sp->plane_sample_offset=(uint8)s; | |
693 | sp->write_cursample=s; | |
694 | sp->write_curstrile=s*tif->tif_dir.td_stripsperimage; | |
695 | if ((sp->in_buffer_file_pos_log==0) || | |
696 | (sp->in_buffer_file_pos-sp->in_buffer_togo!=sp->sos_end[s].in_buffer_file_pos)) | |
697 | { | |
698 | sp->in_buffer_source=sp->sos_end[s].in_buffer_source; | |
699 | sp->in_buffer_next_strile=sp->sos_end[s].in_buffer_next_strile; | |
700 | sp->in_buffer_file_pos=sp->sos_end[s].in_buffer_file_pos; | |
701 | sp->in_buffer_file_pos_log=0; | |
702 | sp->in_buffer_file_togo=sp->sos_end[s].in_buffer_file_togo; | |
703 | sp->in_buffer_togo=0; | |
704 | sp->in_buffer_cur=0; | |
705 | } | |
706 | if (OJPEGWriteHeaderInfo(tif)==0) | |
707 | return(0); | |
708 | } | |
709 | while (sp->write_curstrile<m) | |
710 | { | |
711 | if (sp->libjpeg_jpeg_query_style==0) | |
712 | { | |
713 | if (OJPEGPreDecodeSkipRaw(tif)==0) | |
714 | return(0); | |
715 | } | |
716 | else | |
717 | { | |
718 | if (OJPEGPreDecodeSkipScanlines(tif)==0) | |
719 | return(0); | |
720 | } | |
721 | sp->write_curstrile++; | |
722 | } | |
723 | return(1); | |
724 | } | |
8414a40c | 725 | |
80ed523f VZ |
726 | static int |
727 | OJPEGPreDecodeSkipRaw(TIFF* tif) | |
728 | { | |
729 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
730 | uint32 m; | |
731 | m=sp->lines_per_strile; | |
732 | if (sp->subsampling_convert_state!=0) | |
733 | { | |
734 | if (sp->subsampling_convert_clines-sp->subsampling_convert_state>=m) | |
735 | { | |
736 | sp->subsampling_convert_state+=m; | |
737 | if (sp->subsampling_convert_state==sp->subsampling_convert_clines) | |
738 | sp->subsampling_convert_state=0; | |
739 | return(1); | |
740 | } | |
741 | m-=sp->subsampling_convert_clines-sp->subsampling_convert_state; | |
742 | sp->subsampling_convert_state=0; | |
743 | } | |
744 | while (m>=sp->subsampling_convert_clines) | |
745 | { | |
746 | if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0) | |
747 | return(0); | |
748 | m-=sp->subsampling_convert_clines; | |
749 | } | |
750 | if (m>0) | |
751 | { | |
752 | if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0) | |
753 | return(0); | |
754 | sp->subsampling_convert_state=m; | |
755 | } | |
756 | return(1); | |
757 | } | |
8414a40c | 758 | |
80ed523f VZ |
759 | static int |
760 | OJPEGPreDecodeSkipScanlines(TIFF* tif) | |
761 | { | |
762 | static const char module[]="OJPEGPreDecodeSkipScanlines"; | |
763 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
764 | uint32 m; | |
765 | if (sp->skip_buffer==NULL) | |
766 | { | |
767 | sp->skip_buffer=_TIFFmalloc(sp->bytes_per_line); | |
768 | if (sp->skip_buffer==NULL) | |
769 | { | |
770 | TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); | |
771 | return(0); | |
772 | } | |
773 | } | |
774 | for (m=0; m<sp->lines_per_strile; m++) | |
775 | { | |
776 | if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&sp->skip_buffer,1)==0) | |
777 | return(0); | |
778 | } | |
779 | return(1); | |
780 | } | |
781 | ||
782 | static int | |
783 | OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) | |
784 | { | |
785 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
786 | (void)s; | |
787 | if (sp->libjpeg_jpeg_query_style==0) | |
788 | { | |
789 | if (OJPEGDecodeRaw(tif,buf,cc)==0) | |
790 | return(0); | |
791 | } | |
792 | else | |
793 | { | |
794 | if (OJPEGDecodeScanlines(tif,buf,cc)==0) | |
795 | return(0); | |
796 | } | |
797 | return(1); | |
798 | } | |
8414a40c | 799 | |
80ed523f VZ |
800 | static int |
801 | OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc) | |
802 | { | |
803 | static const char module[]="OJPEGDecodeRaw"; | |
804 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
805 | uint8* m; | |
806 | tmsize_t n; | |
807 | uint8* oy; | |
808 | uint8* ocb; | |
809 | uint8* ocr; | |
810 | uint8* p; | |
811 | uint32 q; | |
812 | uint8* r; | |
813 | uint8 sx,sy; | |
814 | if (cc%sp->bytes_per_line!=0) | |
815 | { | |
816 | TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read"); | |
817 | return(0); | |
818 | } | |
819 | assert(cc>0); | |
820 | m=buf; | |
821 | n=cc; | |
822 | do | |
823 | { | |
824 | if (sp->subsampling_convert_state==0) | |
825 | { | |
826 | if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0) | |
827 | return(0); | |
828 | } | |
829 | oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen; | |
830 | ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen; | |
831 | ocr=sp->subsampling_convert_crbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen; | |
832 | p=m; | |
833 | for (q=0; q<sp->subsampling_convert_clinelenout; q++) | |
834 | { | |
835 | r=oy; | |
836 | for (sy=0; sy<sp->subsampling_ver; sy++) | |
837 | { | |
838 | for (sx=0; sx<sp->subsampling_hor; sx++) | |
839 | *p++=*r++; | |
840 | r+=sp->subsampling_convert_ylinelen-sp->subsampling_hor; | |
841 | } | |
842 | oy+=sp->subsampling_hor; | |
843 | *p++=*ocb++; | |
844 | *p++=*ocr++; | |
845 | } | |
846 | sp->subsampling_convert_state++; | |
847 | if (sp->subsampling_convert_state==sp->subsampling_convert_clines) | |
848 | sp->subsampling_convert_state=0; | |
849 | m+=sp->bytes_per_line; | |
850 | n-=sp->bytes_per_line; | |
851 | } while(n>0); | |
852 | return(1); | |
853 | } | |
8414a40c | 854 | |
80ed523f VZ |
855 | static int |
856 | OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc) | |
857 | { | |
858 | static const char module[]="OJPEGDecodeScanlines"; | |
859 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
860 | uint8* m; | |
861 | tmsize_t n; | |
862 | if (cc%sp->bytes_per_line!=0) | |
863 | { | |
864 | TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read"); | |
865 | return(0); | |
866 | } | |
867 | assert(cc>0); | |
868 | m=buf; | |
869 | n=cc; | |
870 | do | |
871 | { | |
872 | if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&m,1)==0) | |
873 | return(0); | |
874 | m+=sp->bytes_per_line; | |
875 | n-=sp->bytes_per_line; | |
876 | } while(n>0); | |
877 | return(1); | |
878 | } | |
8414a40c VZ |
879 | |
880 | static void | |
80ed523f VZ |
881 | OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc) |
882 | { | |
883 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
884 | (void)buf; | |
885 | (void)cc; | |
886 | sp->write_curstrile++; | |
887 | if (sp->write_curstrile%tif->tif_dir.td_stripsperimage==0) | |
888 | { | |
889 | assert(sp->libjpeg_session_active!=0); | |
890 | OJPEGLibjpegSessionAbort(tif); | |
891 | sp->writeheader_done=0; | |
892 | } | |
893 | } | |
8414a40c | 894 | |
80ed523f VZ |
895 | static int |
896 | OJPEGSetupEncode(TIFF* tif) | |
897 | { | |
898 | static const char module[]="OJPEGSetupEncode"; | |
899 | TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); | |
900 | return(0); | |
901 | } | |
8414a40c | 902 | |
80ed523f VZ |
903 | static int |
904 | OJPEGPreEncode(TIFF* tif, uint16 s) | |
905 | { | |
906 | static const char module[]="OJPEGPreEncode"; | |
907 | (void)s; | |
908 | TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); | |
909 | return(0); | |
910 | } | |
8414a40c VZ |
911 | |
912 | static int | |
80ed523f VZ |
913 | OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s) |
914 | { | |
915 | static const char module[]="OJPEGEncode"; | |
916 | (void)buf; | |
917 | (void)cc; | |
918 | (void)s; | |
919 | TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); | |
920 | return(0); | |
921 | } | |
8414a40c | 922 | |
80ed523f VZ |
923 | static int |
924 | OJPEGPostEncode(TIFF* tif) | |
925 | { | |
926 | static const char module[]="OJPEGPostEncode"; | |
927 | TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); | |
928 | return(0); | |
929 | } | |
8414a40c | 930 | |
8414a40c | 931 | static void |
80ed523f VZ |
932 | OJPEGCleanup(TIFF* tif) |
933 | { | |
934 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
935 | if (sp!=0) | |
936 | { | |
937 | tif->tif_tagmethods.vgetfield=sp->vgetparent; | |
938 | tif->tif_tagmethods.vsetfield=sp->vsetparent; | |
939 | tif->tif_tagmethods.printdir=sp->printdir; | |
940 | if (sp->qtable[0]!=0) | |
941 | _TIFFfree(sp->qtable[0]); | |
942 | if (sp->qtable[1]!=0) | |
943 | _TIFFfree(sp->qtable[1]); | |
944 | if (sp->qtable[2]!=0) | |
945 | _TIFFfree(sp->qtable[2]); | |
946 | if (sp->qtable[3]!=0) | |
947 | _TIFFfree(sp->qtable[3]); | |
948 | if (sp->dctable[0]!=0) | |
949 | _TIFFfree(sp->dctable[0]); | |
950 | if (sp->dctable[1]!=0) | |
951 | _TIFFfree(sp->dctable[1]); | |
952 | if (sp->dctable[2]!=0) | |
953 | _TIFFfree(sp->dctable[2]); | |
954 | if (sp->dctable[3]!=0) | |
955 | _TIFFfree(sp->dctable[3]); | |
956 | if (sp->actable[0]!=0) | |
957 | _TIFFfree(sp->actable[0]); | |
958 | if (sp->actable[1]!=0) | |
959 | _TIFFfree(sp->actable[1]); | |
960 | if (sp->actable[2]!=0) | |
961 | _TIFFfree(sp->actable[2]); | |
962 | if (sp->actable[3]!=0) | |
963 | _TIFFfree(sp->actable[3]); | |
964 | if (sp->libjpeg_session_active!=0) | |
965 | OJPEGLibjpegSessionAbort(tif); | |
966 | if (sp->subsampling_convert_ycbcrbuf!=0) | |
967 | _TIFFfree(sp->subsampling_convert_ycbcrbuf); | |
968 | if (sp->subsampling_convert_ycbcrimage!=0) | |
969 | _TIFFfree(sp->subsampling_convert_ycbcrimage); | |
970 | if (sp->skip_buffer!=0) | |
971 | _TIFFfree(sp->skip_buffer); | |
972 | _TIFFfree(sp); | |
973 | tif->tif_data=NULL; | |
974 | _TIFFSetDefaultCompressionState(tif); | |
975 | } | |
976 | } | |
8414a40c | 977 | |
80ed523f VZ |
978 | static void |
979 | OJPEGSubsamplingCorrect(TIFF* tif) | |
980 | { | |
981 | static const char module[]="OJPEGSubsamplingCorrect"; | |
982 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
983 | uint8 mh; | |
984 | uint8 mv; | |
985 | _TIFFFillStriles( tif ); | |
986 | ||
987 | assert(sp->subsamplingcorrect_done==0); | |
988 | if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) && | |
989 | (tif->tif_dir.td_photometric!=PHOTOMETRIC_ITULAB))) | |
990 | { | |
991 | if (sp->subsampling_tag!=0) | |
992 | TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag not appropriate for this Photometric and/or SamplesPerPixel"); | |
993 | sp->subsampling_hor=1; | |
994 | sp->subsampling_ver=1; | |
995 | sp->subsampling_force_desubsampling_inside_decompression=0; | |
996 | } | |
997 | else | |
998 | { | |
999 | sp->subsamplingcorrect_done=1; | |
1000 | mh=sp->subsampling_hor; | |
1001 | mv=sp->subsampling_ver; | |
1002 | sp->subsamplingcorrect=1; | |
1003 | OJPEGReadHeaderInfoSec(tif); | |
1004 | if (sp->subsampling_force_desubsampling_inside_decompression!=0) | |
1005 | { | |
1006 | sp->subsampling_hor=1; | |
1007 | sp->subsampling_ver=1; | |
1008 | } | |
1009 | sp->subsamplingcorrect=0; | |
1010 | if (((sp->subsampling_hor!=mh) || (sp->subsampling_ver!=mv)) && (sp->subsampling_force_desubsampling_inside_decompression==0)) | |
1011 | { | |
1012 | if (sp->subsampling_tag==0) | |
1013 | TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data [%d,%d] does not match default values [2,2]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver); | |
1014 | else | |
1015 | TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data [%d,%d] does not match subsampling tag values [%d,%d]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver,mh,mv); | |
1016 | } | |
1017 | if (sp->subsampling_force_desubsampling_inside_decompression!=0) | |
1018 | { | |
1019 | if (sp->subsampling_tag==0) | |
1020 | TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data does not match default values [2,2] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression"); | |
1021 | else | |
1022 | TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data does not match subsampling tag values [%d,%d] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression",mh,mv); | |
1023 | } | |
1024 | if (sp->subsampling_force_desubsampling_inside_decompression==0) | |
1025 | { | |
1026 | if (sp->subsampling_hor<sp->subsampling_ver) | |
1027 | TIFFWarningExt(tif->tif_clientdata,module,"Subsampling values [%d,%d] are not allowed in TIFF",sp->subsampling_hor,sp->subsampling_ver); | |
1028 | } | |
1029 | } | |
1030 | sp->subsamplingcorrect_done=1; | |
1031 | } | |
8414a40c | 1032 | |
80ed523f VZ |
1033 | static int |
1034 | OJPEGReadHeaderInfo(TIFF* tif) | |
1035 | { | |
1036 | static const char module[]="OJPEGReadHeaderInfo"; | |
1037 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
1038 | assert(sp->readheader_done==0); | |
1039 | sp->image_width=tif->tif_dir.td_imagewidth; | |
1040 | sp->image_length=tif->tif_dir.td_imagelength; | |
1041 | if isTiled(tif) | |
1042 | { | |
1043 | sp->strile_width=tif->tif_dir.td_tilewidth; | |
1044 | sp->strile_length=tif->tif_dir.td_tilelength; | |
1045 | sp->strile_length_total=((sp->image_length+sp->strile_length-1)/sp->strile_length)*sp->strile_length; | |
1046 | } | |
1047 | else | |
1048 | { | |
1049 | sp->strile_width=sp->image_width; | |
1050 | sp->strile_length=tif->tif_dir.td_rowsperstrip; | |
1051 | sp->strile_length_total=sp->image_length; | |
1052 | } | |
1053 | if (tif->tif_dir.td_samplesperpixel==1) | |
1054 | { | |
1055 | sp->samples_per_pixel=1; | |
1056 | sp->plane_sample_offset=0; | |
1057 | sp->samples_per_pixel_per_plane=sp->samples_per_pixel; | |
1058 | sp->subsampling_hor=1; | |
1059 | sp->subsampling_ver=1; | |
1060 | } | |
1061 | else | |
1062 | { | |
1063 | if (tif->tif_dir.td_samplesperpixel!=3) | |
1064 | { | |
1065 | TIFFErrorExt(tif->tif_clientdata,module,"SamplesPerPixel %d not supported for this compression scheme",sp->samples_per_pixel); | |
1066 | return(0); | |
1067 | } | |
1068 | sp->samples_per_pixel=3; | |
1069 | sp->plane_sample_offset=0; | |
1070 | if (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG) | |
1071 | sp->samples_per_pixel_per_plane=3; | |
1072 | else | |
1073 | sp->samples_per_pixel_per_plane=1; | |
1074 | } | |
1075 | if (sp->strile_length<sp->image_length) | |
1076 | { | |
1077 | if (sp->strile_length%(sp->subsampling_ver*8)!=0) | |
1078 | { | |
1079 | TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and image strip/tile length"); | |
1080 | return(0); | |
1081 | } | |
1082 | sp->restart_interval=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8))*(sp->strile_length/(sp->subsampling_ver*8)); | |
1083 | } | |
1084 | if (OJPEGReadHeaderInfoSec(tif)==0) | |
1085 | return(0); | |
1086 | sp->sos_end[0].log=1; | |
1087 | sp->sos_end[0].in_buffer_source=sp->in_buffer_source; | |
1088 | sp->sos_end[0].in_buffer_next_strile=sp->in_buffer_next_strile; | |
1089 | sp->sos_end[0].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo; | |
1090 | sp->sos_end[0].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo; | |
1091 | sp->readheader_done=1; | |
1092 | return(1); | |
1093 | } | |
1094 | ||
1095 | static int | |
1096 | OJPEGReadSecondarySos(TIFF* tif, uint16 s) | |
1097 | { | |
1098 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
1099 | uint8 m; | |
1100 | assert(s>0); | |
1101 | assert(s<3); | |
1102 | assert(sp->sos_end[0].log!=0); | |
1103 | assert(sp->sos_end[s].log==0); | |
1104 | sp->plane_sample_offset=s-1; | |
1105 | while(sp->sos_end[sp->plane_sample_offset].log==0) | |
1106 | sp->plane_sample_offset--; | |
1107 | sp->in_buffer_source=sp->sos_end[sp->plane_sample_offset].in_buffer_source; | |
1108 | sp->in_buffer_next_strile=sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile; | |
1109 | sp->in_buffer_file_pos=sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos; | |
1110 | sp->in_buffer_file_pos_log=0; | |
1111 | sp->in_buffer_file_togo=sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo; | |
1112 | sp->in_buffer_togo=0; | |
1113 | sp->in_buffer_cur=0; | |
1114 | while(sp->plane_sample_offset<s) | |
1115 | { | |
1116 | do | |
1117 | { | |
1118 | if (OJPEGReadByte(sp,&m)==0) | |
1119 | return(0); | |
1120 | if (m==255) | |
1121 | { | |
1122 | do | |
1123 | { | |
1124 | if (OJPEGReadByte(sp,&m)==0) | |
1125 | return(0); | |
1126 | if (m!=255) | |
1127 | break; | |
1128 | } while(1); | |
1129 | if (m==JPEG_MARKER_SOS) | |
1130 | break; | |
1131 | } | |
1132 | } while(1); | |
1133 | sp->plane_sample_offset++; | |
1134 | if (OJPEGReadHeaderInfoSecStreamSos(tif)==0) | |
1135 | return(0); | |
1136 | sp->sos_end[sp->plane_sample_offset].log=1; | |
1137 | sp->sos_end[sp->plane_sample_offset].in_buffer_source=sp->in_buffer_source; | |
1138 | sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile=sp->in_buffer_next_strile; | |
1139 | sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo; | |
1140 | sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo; | |
1141 | } | |
1142 | return(1); | |
1143 | } | |
1144 | ||
1145 | static int | |
1146 | OJPEGWriteHeaderInfo(TIFF* tif) | |
1147 | { | |
1148 | static const char module[]="OJPEGWriteHeaderInfo"; | |
1149 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
1150 | uint8** m; | |
1151 | uint32 n; | |
1152 | /* if a previous attempt failed, don't try again */ | |
1153 | if (sp->libjpeg_session_active != 0) | |
1154 | return 0; | |
1155 | sp->out_state=ososSoi; | |
1156 | sp->restart_index=0; | |
1157 | jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr)); | |
1158 | sp->libjpeg_jpeg_error_mgr.output_message=OJPEGLibjpegJpegErrorMgrOutputMessage; | |
1159 | sp->libjpeg_jpeg_error_mgr.error_exit=OJPEGLibjpegJpegErrorMgrErrorExit; | |
1160 | sp->libjpeg_jpeg_decompress_struct.err=&(sp->libjpeg_jpeg_error_mgr); | |
1161 | sp->libjpeg_jpeg_decompress_struct.client_data=(void*)tif; | |
1162 | if (jpeg_create_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0) | |
1163 | return(0); | |
1164 | sp->libjpeg_session_active=1; | |
1165 | sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=0; | |
1166 | sp->libjpeg_jpeg_source_mgr.init_source=OJPEGLibjpegJpegSourceMgrInitSource; | |
1167 | sp->libjpeg_jpeg_source_mgr.fill_input_buffer=OJPEGLibjpegJpegSourceMgrFillInputBuffer; | |
1168 | sp->libjpeg_jpeg_source_mgr.skip_input_data=OJPEGLibjpegJpegSourceMgrSkipInputData; | |
1169 | sp->libjpeg_jpeg_source_mgr.resync_to_restart=OJPEGLibjpegJpegSourceMgrResyncToRestart; | |
1170 | sp->libjpeg_jpeg_source_mgr.term_source=OJPEGLibjpegJpegSourceMgrTermSource; | |
1171 | sp->libjpeg_jpeg_decompress_struct.src=&(sp->libjpeg_jpeg_source_mgr); | |
1172 | if (jpeg_read_header_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),1)==0) | |
1173 | return(0); | |
1174 | if ((sp->subsampling_force_desubsampling_inside_decompression==0) && (sp->samples_per_pixel_per_plane>1)) | |
1175 | { | |
1176 | sp->libjpeg_jpeg_decompress_struct.raw_data_out=1; | |
1177 | #if JPEG_LIB_VERSION >= 70 | |
1178 | sp->libjpeg_jpeg_decompress_struct.do_fancy_upsampling=FALSE; | |
1179 | #endif | |
1180 | sp->libjpeg_jpeg_query_style=0; | |
1181 | if (sp->subsampling_convert_log==0) | |
1182 | { | |
1183 | assert(sp->subsampling_convert_ycbcrbuf==0); | |
1184 | assert(sp->subsampling_convert_ycbcrimage==0); | |
1185 | sp->subsampling_convert_ylinelen=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8)*sp->subsampling_hor*8); | |
1186 | sp->subsampling_convert_ylines=sp->subsampling_ver*8; | |
1187 | sp->subsampling_convert_clinelen=sp->subsampling_convert_ylinelen/sp->subsampling_hor; | |
1188 | sp->subsampling_convert_clines=8; | |
1189 | sp->subsampling_convert_ybuflen=sp->subsampling_convert_ylinelen*sp->subsampling_convert_ylines; | |
1190 | sp->subsampling_convert_cbuflen=sp->subsampling_convert_clinelen*sp->subsampling_convert_clines; | |
1191 | sp->subsampling_convert_ycbcrbuflen=sp->subsampling_convert_ybuflen+2*sp->subsampling_convert_cbuflen; | |
1192 | sp->subsampling_convert_ycbcrbuf=_TIFFmalloc(sp->subsampling_convert_ycbcrbuflen); | |
1193 | if (sp->subsampling_convert_ycbcrbuf==0) | |
1194 | { | |
1195 | TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); | |
1196 | return(0); | |
1197 | } | |
1198 | sp->subsampling_convert_ybuf=sp->subsampling_convert_ycbcrbuf; | |
1199 | sp->subsampling_convert_cbbuf=sp->subsampling_convert_ybuf+sp->subsampling_convert_ybuflen; | |
1200 | sp->subsampling_convert_crbuf=sp->subsampling_convert_cbbuf+sp->subsampling_convert_cbuflen; | |
1201 | sp->subsampling_convert_ycbcrimagelen=3+sp->subsampling_convert_ylines+2*sp->subsampling_convert_clines; | |
1202 | sp->subsampling_convert_ycbcrimage=_TIFFmalloc(sp->subsampling_convert_ycbcrimagelen*sizeof(uint8*)); | |
1203 | if (sp->subsampling_convert_ycbcrimage==0) | |
1204 | { | |
1205 | TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); | |
1206 | return(0); | |
1207 | } | |
1208 | m=sp->subsampling_convert_ycbcrimage; | |
1209 | *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3); | |
1210 | *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines); | |
1211 | *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines+sp->subsampling_convert_clines); | |
1212 | for (n=0; n<sp->subsampling_convert_ylines; n++) | |
1213 | *m++=sp->subsampling_convert_ybuf+n*sp->subsampling_convert_ylinelen; | |
1214 | for (n=0; n<sp->subsampling_convert_clines; n++) | |
1215 | *m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen; | |
1216 | for (n=0; n<sp->subsampling_convert_clines; n++) | |
1217 | *m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen; | |
1218 | sp->subsampling_convert_clinelenout=((sp->strile_width+sp->subsampling_hor-1)/sp->subsampling_hor); | |
1219 | sp->subsampling_convert_state=0; | |
1220 | sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2); | |
1221 | sp->lines_per_strile=((sp->strile_length+sp->subsampling_ver-1)/sp->subsampling_ver); | |
1222 | sp->subsampling_convert_log=1; | |
1223 | } | |
1224 | } | |
1225 | else | |
1226 | { | |
1227 | sp->libjpeg_jpeg_decompress_struct.jpeg_color_space=JCS_UNKNOWN; | |
1228 | sp->libjpeg_jpeg_decompress_struct.out_color_space=JCS_UNKNOWN; | |
1229 | sp->libjpeg_jpeg_query_style=1; | |
1230 | sp->bytes_per_line=sp->samples_per_pixel_per_plane*sp->strile_width; | |
1231 | sp->lines_per_strile=sp->strile_length; | |
1232 | } | |
1233 | if (jpeg_start_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0) | |
1234 | return(0); | |
1235 | sp->writeheader_done=1; | |
1236 | return(1); | |
1237 | } | |
8414a40c VZ |
1238 | |
1239 | static void | |
80ed523f VZ |
1240 | OJPEGLibjpegSessionAbort(TIFF* tif) |
1241 | { | |
1242 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
1243 | assert(sp->libjpeg_session_active!=0); | |
1244 | jpeg_destroy((jpeg_common_struct*)(&(sp->libjpeg_jpeg_decompress_struct))); | |
1245 | sp->libjpeg_session_active=0; | |
1246 | } | |
1247 | ||
8414a40c | 1248 | static int |
80ed523f VZ |
1249 | OJPEGReadHeaderInfoSec(TIFF* tif) |
1250 | { | |
1251 | static const char module[]="OJPEGReadHeaderInfoSec"; | |
1252 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
1253 | uint8 m; | |
1254 | uint16 n; | |
1255 | uint8 o; | |
1256 | if (sp->file_size==0) | |
1257 | sp->file_size=TIFFGetFileSize(tif); | |
1258 | if (sp->jpeg_interchange_format!=0) | |
1259 | { | |
1260 | if (sp->jpeg_interchange_format>=sp->file_size) | |
1261 | { | |
1262 | sp->jpeg_interchange_format=0; | |
1263 | sp->jpeg_interchange_format_length=0; | |
1264 | } | |
1265 | else | |
1266 | { | |
1267 | if ((sp->jpeg_interchange_format_length==0) || (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size)) | |
1268 | sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format; | |
1269 | } | |
1270 | } | |
1271 | sp->in_buffer_source=osibsNotSetYet; | |
1272 | sp->in_buffer_next_strile=0; | |
1273 | sp->in_buffer_strile_count=tif->tif_dir.td_nstrips; | |
1274 | sp->in_buffer_file_togo=0; | |
1275 | sp->in_buffer_togo=0; | |
1276 | do | |
1277 | { | |
1278 | if (OJPEGReadBytePeek(sp,&m)==0) | |
1279 | return(0); | |
1280 | if (m!=255) | |
1281 | break; | |
1282 | OJPEGReadByteAdvance(sp); | |
1283 | do | |
1284 | { | |
1285 | if (OJPEGReadByte(sp,&m)==0) | |
1286 | return(0); | |
1287 | } while(m==255); | |
1288 | switch(m) | |
1289 | { | |
1290 | case JPEG_MARKER_SOI: | |
1291 | /* this type of marker has no data, and should be skipped */ | |
1292 | break; | |
1293 | case JPEG_MARKER_COM: | |
1294 | case JPEG_MARKER_APP0: | |
1295 | case JPEG_MARKER_APP0+1: | |
1296 | case JPEG_MARKER_APP0+2: | |
1297 | case JPEG_MARKER_APP0+3: | |
1298 | case JPEG_MARKER_APP0+4: | |
1299 | case JPEG_MARKER_APP0+5: | |
1300 | case JPEG_MARKER_APP0+6: | |
1301 | case JPEG_MARKER_APP0+7: | |
1302 | case JPEG_MARKER_APP0+8: | |
1303 | case JPEG_MARKER_APP0+9: | |
1304 | case JPEG_MARKER_APP0+10: | |
1305 | case JPEG_MARKER_APP0+11: | |
1306 | case JPEG_MARKER_APP0+12: | |
1307 | case JPEG_MARKER_APP0+13: | |
1308 | case JPEG_MARKER_APP0+14: | |
1309 | case JPEG_MARKER_APP0+15: | |
1310 | /* this type of marker has data, but it has no use to us (and no place here) and should be skipped */ | |
1311 | if (OJPEGReadWord(sp,&n)==0) | |
1312 | return(0); | |
1313 | if (n<2) | |
1314 | { | |
1315 | if (sp->subsamplingcorrect==0) | |
1316 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data"); | |
1317 | return(0); | |
1318 | } | |
1319 | if (n>2) | |
1320 | OJPEGReadSkip(sp,n-2); | |
1321 | break; | |
1322 | case JPEG_MARKER_DRI: | |
1323 | if (OJPEGReadHeaderInfoSecStreamDri(tif)==0) | |
1324 | return(0); | |
1325 | break; | |
1326 | case JPEG_MARKER_DQT: | |
1327 | if (OJPEGReadHeaderInfoSecStreamDqt(tif)==0) | |
1328 | return(0); | |
1329 | break; | |
1330 | case JPEG_MARKER_DHT: | |
1331 | if (OJPEGReadHeaderInfoSecStreamDht(tif)==0) | |
1332 | return(0); | |
1333 | break; | |
1334 | case JPEG_MARKER_SOF0: | |
1335 | case JPEG_MARKER_SOF1: | |
1336 | case JPEG_MARKER_SOF3: | |
1337 | if (OJPEGReadHeaderInfoSecStreamSof(tif,m)==0) | |
1338 | return(0); | |
1339 | if (sp->subsamplingcorrect!=0) | |
1340 | return(1); | |
1341 | break; | |
1342 | case JPEG_MARKER_SOS: | |
1343 | if (sp->subsamplingcorrect!=0) | |
1344 | return(1); | |
1345 | assert(sp->plane_sample_offset==0); | |
1346 | if (OJPEGReadHeaderInfoSecStreamSos(tif)==0) | |
1347 | return(0); | |
1348 | break; | |
1349 | default: | |
1350 | TIFFErrorExt(tif->tif_clientdata,module,"Unknown marker type %d in JPEG data",m); | |
1351 | return(0); | |
1352 | } | |
1353 | } while(m!=JPEG_MARKER_SOS); | |
1354 | if (sp->subsamplingcorrect) | |
1355 | return(1); | |
1356 | if (sp->sof_log==0) | |
1357 | { | |
1358 | if (OJPEGReadHeaderInfoSecTablesQTable(tif)==0) | |
1359 | return(0); | |
1360 | sp->sof_marker_id=JPEG_MARKER_SOF0; | |
1361 | for (o=0; o<sp->samples_per_pixel; o++) | |
1362 | sp->sof_c[o]=o; | |
1363 | sp->sof_hv[0]=((sp->subsampling_hor<<4)|sp->subsampling_ver); | |
1364 | for (o=1; o<sp->samples_per_pixel; o++) | |
1365 | sp->sof_hv[o]=17; | |
1366 | sp->sof_x=sp->strile_width; | |
1367 | sp->sof_y=sp->strile_length_total; | |
1368 | sp->sof_log=1; | |
1369 | if (OJPEGReadHeaderInfoSecTablesDcTable(tif)==0) | |
1370 | return(0); | |
1371 | if (OJPEGReadHeaderInfoSecTablesAcTable(tif)==0) | |
1372 | return(0); | |
1373 | for (o=1; o<sp->samples_per_pixel; o++) | |
1374 | sp->sos_cs[o]=o; | |
1375 | } | |
1376 | return(1); | |
1377 | } | |
8414a40c VZ |
1378 | |
1379 | static int | |
80ed523f VZ |
1380 | OJPEGReadHeaderInfoSecStreamDri(TIFF* tif) |
1381 | { | |
1382 | /* this could easilly cause trouble in some cases... but no such cases have occured sofar */ | |
1383 | static const char module[]="OJPEGReadHeaderInfoSecStreamDri"; | |
1384 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
1385 | uint16 m; | |
1386 | if (OJPEGReadWord(sp,&m)==0) | |
1387 | return(0); | |
1388 | if (m!=4) | |
1389 | { | |
1390 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DRI marker in JPEG data"); | |
1391 | return(0); | |
1392 | } | |
1393 | if (OJPEGReadWord(sp,&m)==0) | |
1394 | return(0); | |
1395 | sp->restart_interval=m; | |
1396 | return(1); | |
1397 | } | |
8414a40c VZ |
1398 | |
1399 | static int | |
80ed523f VZ |
1400 | OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif) |
1401 | { | |
1402 | /* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */ | |
1403 | static const char module[]="OJPEGReadHeaderInfoSecStreamDqt"; | |
1404 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
1405 | uint16 m; | |
1406 | uint32 na; | |
1407 | uint8* nb; | |
1408 | uint8 o; | |
1409 | if (OJPEGReadWord(sp,&m)==0) | |
1410 | return(0); | |
1411 | if (m<=2) | |
1412 | { | |
1413 | if (sp->subsamplingcorrect==0) | |
1414 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data"); | |
1415 | return(0); | |
1416 | } | |
1417 | if (sp->subsamplingcorrect!=0) | |
1418 | OJPEGReadSkip(sp,m-2); | |
1419 | else | |
1420 | { | |
1421 | m-=2; | |
1422 | do | |
1423 | { | |
1424 | if (m<65) | |
1425 | { | |
1426 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data"); | |
1427 | return(0); | |
1428 | } | |
1429 | na=sizeof(uint32)+69; | |
1430 | nb=_TIFFmalloc(na); | |
1431 | if (nb==0) | |
1432 | { | |
1433 | TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); | |
1434 | return(0); | |
1435 | } | |
1436 | *(uint32*)nb=na; | |
1437 | nb[sizeof(uint32)]=255; | |
1438 | nb[sizeof(uint32)+1]=JPEG_MARKER_DQT; | |
1439 | nb[sizeof(uint32)+2]=0; | |
1440 | nb[sizeof(uint32)+3]=67; | |
1441 | if (OJPEGReadBlock(sp,65,&nb[sizeof(uint32)+4])==0) { | |
1442 | _TIFFfree(nb); | |
1443 | return(0); | |
1444 | } | |
1445 | o=nb[sizeof(uint32)+4]&15; | |
1446 | if (3<o) | |
1447 | { | |
1448 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data"); | |
1449 | _TIFFfree(nb); | |
1450 | return(0); | |
1451 | } | |
1452 | if (sp->qtable[o]!=0) | |
1453 | _TIFFfree(sp->qtable[o]); | |
1454 | sp->qtable[o]=nb; | |
1455 | m-=65; | |
1456 | } while(m>0); | |
1457 | } | |
1458 | return(1); | |
1459 | } | |
8414a40c VZ |
1460 | |
1461 | static int | |
80ed523f VZ |
1462 | OJPEGReadHeaderInfoSecStreamDht(TIFF* tif) |
1463 | { | |
1464 | /* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */ | |
1465 | /* TODO: the following assumes there is only one table in this marker... but i'm not quite sure that assumption is guaranteed correct */ | |
1466 | static const char module[]="OJPEGReadHeaderInfoSecStreamDht"; | |
1467 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
1468 | uint16 m; | |
1469 | uint32 na; | |
1470 | uint8* nb; | |
1471 | uint8 o; | |
1472 | if (OJPEGReadWord(sp,&m)==0) | |
1473 | return(0); | |
1474 | if (m<=2) | |
1475 | { | |
1476 | if (sp->subsamplingcorrect==0) | |
1477 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data"); | |
1478 | return(0); | |
1479 | } | |
1480 | if (sp->subsamplingcorrect!=0) | |
1481 | { | |
1482 | OJPEGReadSkip(sp,m-2); | |
1483 | } | |
1484 | else | |
1485 | { | |
1486 | na=sizeof(uint32)+2+m; | |
1487 | nb=_TIFFmalloc(na); | |
1488 | if (nb==0) | |
1489 | { | |
1490 | TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); | |
1491 | return(0); | |
1492 | } | |
1493 | *(uint32*)nb=na; | |
1494 | nb[sizeof(uint32)]=255; | |
1495 | nb[sizeof(uint32)+1]=JPEG_MARKER_DHT; | |
1496 | nb[sizeof(uint32)+2]=(m>>8); | |
1497 | nb[sizeof(uint32)+3]=(m&255); | |
1498 | if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0) | |
1499 | return(0); | |
1500 | o=nb[sizeof(uint32)+4]; | |
1501 | if ((o&240)==0) | |
1502 | { | |
1503 | if (3<o) | |
1504 | { | |
1505 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data"); | |
1506 | return(0); | |
1507 | } | |
1508 | if (sp->dctable[o]!=0) | |
1509 | _TIFFfree(sp->dctable[o]); | |
1510 | sp->dctable[o]=nb; | |
1511 | } | |
1512 | else | |
1513 | { | |
1514 | if ((o&240)!=16) | |
1515 | { | |
1516 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data"); | |
1517 | return(0); | |
1518 | } | |
1519 | o&=15; | |
1520 | if (3<o) | |
1521 | { | |
1522 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data"); | |
1523 | return(0); | |
1524 | } | |
1525 | if (sp->actable[o]!=0) | |
1526 | _TIFFfree(sp->actable[o]); | |
1527 | sp->actable[o]=nb; | |
1528 | } | |
1529 | } | |
1530 | return(1); | |
1531 | } | |
8414a40c VZ |
1532 | |
1533 | static int | |
80ed523f VZ |
1534 | OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id) |
1535 | { | |
1536 | /* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */ | |
1537 | static const char module[]="OJPEGReadHeaderInfoSecStreamSof"; | |
1538 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
1539 | uint16 m; | |
1540 | uint16 n; | |
1541 | uint8 o; | |
1542 | uint16 p; | |
1543 | uint16 q; | |
1544 | if (sp->sof_log!=0) | |
1545 | { | |
1546 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data"); | |
1547 | return(0); | |
1548 | } | |
1549 | if (sp->subsamplingcorrect==0) | |
1550 | sp->sof_marker_id=marker_id; | |
1551 | /* Lf: data length */ | |
1552 | if (OJPEGReadWord(sp,&m)==0) | |
1553 | return(0); | |
1554 | if (m<11) | |
1555 | { | |
1556 | if (sp->subsamplingcorrect==0) | |
1557 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data"); | |
1558 | return(0); | |
1559 | } | |
1560 | m-=8; | |
1561 | if (m%3!=0) | |
1562 | { | |
1563 | if (sp->subsamplingcorrect==0) | |
1564 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data"); | |
1565 | return(0); | |
1566 | } | |
1567 | n=m/3; | |
1568 | if (sp->subsamplingcorrect==0) | |
1569 | { | |
1570 | if (n!=sp->samples_per_pixel) | |
1571 | { | |
1572 | TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of samples"); | |
1573 | return(0); | |
1574 | } | |
1575 | } | |
1576 | /* P: Sample precision */ | |
1577 | if (OJPEGReadByte(sp,&o)==0) | |
1578 | return(0); | |
1579 | if (o!=8) | |
1580 | { | |
1581 | if (sp->subsamplingcorrect==0) | |
1582 | TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of bits per sample"); | |
1583 | return(0); | |
1584 | } | |
1585 | /* Y: Number of lines, X: Number of samples per line */ | |
1586 | if (sp->subsamplingcorrect) | |
1587 | OJPEGReadSkip(sp,4); | |
1588 | else | |
1589 | { | |
1590 | /* Y: Number of lines */ | |
1591 | if (OJPEGReadWord(sp,&p)==0) | |
1592 | return(0); | |
1593 | if (((uint32)p<sp->image_length) && ((uint32)p<sp->strile_length_total)) | |
1594 | { | |
1595 | TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected height"); | |
1596 | return(0); | |
1597 | } | |
1598 | sp->sof_y=p; | |
1599 | /* X: Number of samples per line */ | |
1600 | if (OJPEGReadWord(sp,&p)==0) | |
1601 | return(0); | |
1602 | if (((uint32)p<sp->image_width) && ((uint32)p<sp->strile_width)) | |
1603 | { | |
1604 | TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected width"); | |
1605 | return(0); | |
1606 | } | |
1607 | if ((uint32)p>sp->strile_width) | |
1608 | { | |
1609 | TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data image width exceeds expected image width"); | |
1610 | return(0); | |
1611 | } | |
1612 | sp->sof_x=p; | |
1613 | } | |
1614 | /* Nf: Number of image components in frame */ | |
1615 | if (OJPEGReadByte(sp,&o)==0) | |
1616 | return(0); | |
1617 | if (o!=n) | |
1618 | { | |
1619 | if (sp->subsamplingcorrect==0) | |
1620 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data"); | |
1621 | return(0); | |
1622 | } | |
1623 | /* per component stuff */ | |
1624 | /* TODO: double-check that flow implies that n cannot be as big as to make us overflow sof_c, sof_hv and sof_tq arrays */ | |
1625 | for (q=0; q<n; q++) | |
1626 | { | |
1627 | /* C: Component identifier */ | |
1628 | if (OJPEGReadByte(sp,&o)==0) | |
1629 | return(0); | |
1630 | if (sp->subsamplingcorrect==0) | |
1631 | sp->sof_c[q]=o; | |
1632 | /* H: Horizontal sampling factor, and V: Vertical sampling factor */ | |
1633 | if (OJPEGReadByte(sp,&o)==0) | |
1634 | return(0); | |
1635 | if (sp->subsamplingcorrect!=0) | |
1636 | { | |
1637 | if (q==0) | |
1638 | { | |
1639 | sp->subsampling_hor=(o>>4); | |
1640 | sp->subsampling_ver=(o&15); | |
1641 | if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) || | |
1642 | ((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4))) | |
1643 | sp->subsampling_force_desubsampling_inside_decompression=1; | |
1644 | } | |
1645 | else | |
1646 | { | |
1647 | if (o!=17) | |
1648 | sp->subsampling_force_desubsampling_inside_decompression=1; | |
1649 | } | |
1650 | } | |
1651 | else | |
1652 | { | |
1653 | sp->sof_hv[q]=o; | |
1654 | if (sp->subsampling_force_desubsampling_inside_decompression==0) | |
1655 | { | |
1656 | if (q==0) | |
1657 | { | |
1658 | if (o!=((sp->subsampling_hor<<4)|sp->subsampling_ver)) | |
1659 | { | |
1660 | TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values"); | |
1661 | return(0); | |
1662 | } | |
1663 | } | |
1664 | else | |
1665 | { | |
1666 | if (o!=17) | |
1667 | { | |
1668 | TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values"); | |
1669 | return(0); | |
1670 | } | |
1671 | } | |
1672 | } | |
1673 | } | |
1674 | /* Tq: Quantization table destination selector */ | |
1675 | if (OJPEGReadByte(sp,&o)==0) | |
1676 | return(0); | |
1677 | if (sp->subsamplingcorrect==0) | |
1678 | sp->sof_tq[q]=o; | |
1679 | } | |
1680 | if (sp->subsamplingcorrect==0) | |
1681 | sp->sof_log=1; | |
1682 | return(1); | |
1683 | } | |
8414a40c | 1684 | |
80ed523f VZ |
1685 | static int |
1686 | OJPEGReadHeaderInfoSecStreamSos(TIFF* tif) | |
1687 | { | |
1688 | /* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */ | |
1689 | static const char module[]="OJPEGReadHeaderInfoSecStreamSos"; | |
1690 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
1691 | uint16 m; | |
1692 | uint8 n; | |
1693 | uint8 o; | |
1694 | assert(sp->subsamplingcorrect==0); | |
1695 | if (sp->sof_log==0) | |
1696 | { | |
1697 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data"); | |
1698 | return(0); | |
1699 | } | |
1700 | /* Ls */ | |
1701 | if (OJPEGReadWord(sp,&m)==0) | |
1702 | return(0); | |
1703 | if (m!=6+sp->samples_per_pixel_per_plane*2) | |
1704 | { | |
1705 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data"); | |
1706 | return(0); | |
1707 | } | |
1708 | /* Ns */ | |
1709 | if (OJPEGReadByte(sp,&n)==0) | |
1710 | return(0); | |
1711 | if (n!=sp->samples_per_pixel_per_plane) | |
1712 | { | |
1713 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data"); | |
1714 | return(0); | |
1715 | } | |
1716 | /* Cs, Td, and Ta */ | |
1717 | for (o=0; o<sp->samples_per_pixel_per_plane; o++) | |
1718 | { | |
1719 | /* Cs */ | |
1720 | if (OJPEGReadByte(sp,&n)==0) | |
1721 | return(0); | |
1722 | sp->sos_cs[sp->plane_sample_offset+o]=n; | |
1723 | /* Td and Ta */ | |
1724 | if (OJPEGReadByte(sp,&n)==0) | |
1725 | return(0); | |
1726 | sp->sos_tda[sp->plane_sample_offset+o]=n; | |
1727 | } | |
1728 | /* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as per LibJpeg source */ | |
1729 | OJPEGReadSkip(sp,3); | |
1730 | return(1); | |
1731 | } | |
8414a40c VZ |
1732 | |
1733 | static int | |
80ed523f VZ |
1734 | OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif) |
1735 | { | |
1736 | static const char module[]="OJPEGReadHeaderInfoSecTablesQTable"; | |
1737 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
1738 | uint8 m; | |
1739 | uint8 n; | |
1740 | uint32 oa; | |
1741 | uint8* ob; | |
1742 | uint32 p; | |
1743 | if (sp->qtable_offset[0]==0) | |
1744 | { | |
1745 | TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables"); | |
1746 | return(0); | |
1747 | } | |
1748 | sp->in_buffer_file_pos_log=0; | |
1749 | for (m=0; m<sp->samples_per_pixel; m++) | |
1750 | { | |
1751 | if ((sp->qtable_offset[m]!=0) && ((m==0) || (sp->qtable_offset[m]!=sp->qtable_offset[m-1]))) | |
1752 | { | |
1753 | for (n=0; n<m-1; n++) | |
1754 | { | |
1755 | if (sp->qtable_offset[m]==sp->qtable_offset[n]) | |
1756 | { | |
1757 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegQTables tag value"); | |
1758 | return(0); | |
1759 | } | |
1760 | } | |
1761 | oa=sizeof(uint32)+69; | |
1762 | ob=_TIFFmalloc(oa); | |
1763 | if (ob==0) | |
1764 | { | |
1765 | TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); | |
1766 | return(0); | |
1767 | } | |
1768 | *(uint32*)ob=oa; | |
1769 | ob[sizeof(uint32)]=255; | |
1770 | ob[sizeof(uint32)+1]=JPEG_MARKER_DQT; | |
1771 | ob[sizeof(uint32)+2]=0; | |
1772 | ob[sizeof(uint32)+3]=67; | |
1773 | ob[sizeof(uint32)+4]=m; | |
1774 | TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET); | |
1775 | p=TIFFReadFile(tif,&ob[sizeof(uint32)+5],64); | |
1776 | if (p!=64) | |
1777 | return(0); | |
1778 | sp->qtable[m]=ob; | |
1779 | sp->sof_tq[m]=m; | |
1780 | } | |
1781 | else | |
1782 | sp->sof_tq[m]=sp->sof_tq[m-1]; | |
1783 | } | |
1784 | return(1); | |
1785 | } | |
8414a40c VZ |
1786 | |
1787 | static int | |
80ed523f | 1788 | OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif) |
8414a40c | 1789 | { |
80ed523f VZ |
1790 | static const char module[]="OJPEGReadHeaderInfoSecTablesDcTable"; |
1791 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
1792 | uint8 m; | |
1793 | uint8 n; | |
1794 | uint8 o[16]; | |
1795 | uint32 p; | |
1796 | uint32 q; | |
1797 | uint32 ra; | |
1798 | uint8* rb; | |
1799 | if (sp->dctable_offset[0]==0) | |
1800 | { | |
1801 | TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables"); | |
1802 | return(0); | |
1803 | } | |
1804 | sp->in_buffer_file_pos_log=0; | |
1805 | for (m=0; m<sp->samples_per_pixel; m++) | |
1806 | { | |
1807 | if ((sp->dctable_offset[m]!=0) && ((m==0) || (sp->dctable_offset[m]!=sp->dctable_offset[m-1]))) | |
1808 | { | |
1809 | for (n=0; n<m-1; n++) | |
1810 | { | |
1811 | if (sp->dctable_offset[m]==sp->dctable_offset[n]) | |
1812 | { | |
1813 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegDcTables tag value"); | |
1814 | return(0); | |
1815 | } | |
1816 | } | |
1817 | TIFFSeekFile(tif,sp->dctable_offset[m],SEEK_SET); | |
1818 | p=TIFFReadFile(tif,o,16); | |
1819 | if (p!=16) | |
1820 | return(0); | |
1821 | q=0; | |
1822 | for (n=0; n<16; n++) | |
1823 | q+=o[n]; | |
1824 | ra=sizeof(uint32)+21+q; | |
1825 | rb=_TIFFmalloc(ra); | |
1826 | if (rb==0) | |
1827 | { | |
1828 | TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); | |
1829 | return(0); | |
1830 | } | |
1831 | *(uint32*)rb=ra; | |
1832 | rb[sizeof(uint32)]=255; | |
1833 | rb[sizeof(uint32)+1]=JPEG_MARKER_DHT; | |
1834 | rb[sizeof(uint32)+2]=((19+q)>>8); | |
1835 | rb[sizeof(uint32)+3]=((19+q)&255); | |
1836 | rb[sizeof(uint32)+4]=m; | |
1837 | for (n=0; n<16; n++) | |
1838 | rb[sizeof(uint32)+5+n]=o[n]; | |
1839 | p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q); | |
1840 | if (p!=q) | |
1841 | return(0); | |
1842 | sp->dctable[m]=rb; | |
1843 | sp->sos_tda[m]=(m<<4); | |
8414a40c | 1844 | } |
80ed523f VZ |
1845 | else |
1846 | sp->sos_tda[m]=sp->sos_tda[m-1]; | |
1847 | } | |
1848 | return(1); | |
1849 | } | |
8414a40c VZ |
1850 | |
1851 | static int | |
80ed523f VZ |
1852 | OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif) |
1853 | { | |
1854 | static const char module[]="OJPEGReadHeaderInfoSecTablesAcTable"; | |
1855 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
1856 | uint8 m; | |
1857 | uint8 n; | |
1858 | uint8 o[16]; | |
1859 | uint32 p; | |
1860 | uint32 q; | |
1861 | uint32 ra; | |
1862 | uint8* rb; | |
1863 | if (sp->actable_offset[0]==0) | |
1864 | { | |
1865 | TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables"); | |
1866 | return(0); | |
1867 | } | |
1868 | sp->in_buffer_file_pos_log=0; | |
1869 | for (m=0; m<sp->samples_per_pixel; m++) | |
1870 | { | |
1871 | if ((sp->actable_offset[m]!=0) && ((m==0) || (sp->actable_offset[m]!=sp->actable_offset[m-1]))) | |
1872 | { | |
1873 | for (n=0; n<m-1; n++) | |
1874 | { | |
1875 | if (sp->actable_offset[m]==sp->actable_offset[n]) | |
1876 | { | |
1877 | TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegAcTables tag value"); | |
1878 | return(0); | |
1879 | } | |
1880 | } | |
1881 | TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET); | |
1882 | p=TIFFReadFile(tif,o,16); | |
1883 | if (p!=16) | |
1884 | return(0); | |
1885 | q=0; | |
1886 | for (n=0; n<16; n++) | |
1887 | q+=o[n]; | |
1888 | ra=sizeof(uint32)+21+q; | |
1889 | rb=_TIFFmalloc(ra); | |
1890 | if (rb==0) | |
1891 | { | |
1892 | TIFFErrorExt(tif->tif_clientdata,module,"Out of memory"); | |
1893 | return(0); | |
1894 | } | |
1895 | *(uint32*)rb=ra; | |
1896 | rb[sizeof(uint32)]=255; | |
1897 | rb[sizeof(uint32)+1]=JPEG_MARKER_DHT; | |
1898 | rb[sizeof(uint32)+2]=((19+q)>>8); | |
1899 | rb[sizeof(uint32)+3]=((19+q)&255); | |
1900 | rb[sizeof(uint32)+4]=(16|m); | |
1901 | for (n=0; n<16; n++) | |
1902 | rb[sizeof(uint32)+5+n]=o[n]; | |
1903 | p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q); | |
1904 | if (p!=q) | |
1905 | return(0); | |
1906 | sp->actable[m]=rb; | |
1907 | sp->sos_tda[m]=(sp->sos_tda[m]|m); | |
1908 | } | |
1909 | else | |
1910 | sp->sos_tda[m]=(sp->sos_tda[m]|(sp->sos_tda[m-1]&15)); | |
1911 | } | |
1912 | return(1); | |
1913 | } | |
1914 | ||
1915 | static int | |
1916 | OJPEGReadBufferFill(OJPEGState* sp) | |
1917 | { | |
1918 | uint16 m; | |
1919 | tmsize_t n; | |
1920 | /* TODO: double-check: when subsamplingcorrect is set, no call to TIFFErrorExt or TIFFWarningExt should be made | |
1921 | * in any other case, seek or read errors should be passed through */ | |
1922 | do | |
1923 | { | |
1924 | if (sp->in_buffer_file_togo!=0) | |
1925 | { | |
1926 | if (sp->in_buffer_file_pos_log==0) | |
1927 | { | |
1928 | TIFFSeekFile(sp->tif,sp->in_buffer_file_pos,SEEK_SET); | |
1929 | sp->in_buffer_file_pos_log=1; | |
1930 | } | |
1931 | m=OJPEG_BUFFER; | |
1932 | if ((uint64)m>sp->in_buffer_file_togo) | |
1933 | m=(uint16)sp->in_buffer_file_togo; | |
1934 | n=TIFFReadFile(sp->tif,sp->in_buffer,(tmsize_t)m); | |
1935 | if (n==0) | |
1936 | return(0); | |
1937 | assert(n>0); | |
1938 | assert(n<=OJPEG_BUFFER); | |
1939 | assert(n<65536); | |
1940 | assert((uint64)n<=sp->in_buffer_file_togo); | |
1941 | m=(uint16)n; | |
1942 | sp->in_buffer_togo=m; | |
1943 | sp->in_buffer_cur=sp->in_buffer; | |
1944 | sp->in_buffer_file_togo-=m; | |
1945 | sp->in_buffer_file_pos+=m; | |
1946 | break; | |
1947 | } | |
1948 | sp->in_buffer_file_pos_log=0; | |
1949 | switch(sp->in_buffer_source) | |
1950 | { | |
1951 | case osibsNotSetYet: | |
1952 | if (sp->jpeg_interchange_format!=0) | |
1953 | { | |
1954 | sp->in_buffer_file_pos=sp->jpeg_interchange_format; | |
1955 | sp->in_buffer_file_togo=sp->jpeg_interchange_format_length; | |
1956 | } | |
1957 | sp->in_buffer_source=osibsJpegInterchangeFormat; | |
1958 | break; | |
1959 | case osibsJpegInterchangeFormat: | |
1960 | sp->in_buffer_source=osibsStrile; | |
1961 | case osibsStrile: | |
1962 | if (!_TIFFFillStriles( sp->tif ) | |
1963 | || sp->tif->tif_dir.td_stripoffset == NULL | |
1964 | || sp->tif->tif_dir.td_stripbytecount == NULL) | |
1965 | return 0; | |
1966 | ||
1967 | if (sp->in_buffer_next_strile==sp->in_buffer_strile_count) | |
1968 | sp->in_buffer_source=osibsEof; | |
1969 | else | |
1970 | { | |
1971 | sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile]; | |
1972 | if (sp->in_buffer_file_pos!=0) | |
1973 | { | |
1974 | if (sp->in_buffer_file_pos>=sp->file_size) | |
1975 | sp->in_buffer_file_pos=0; | |
1976 | else if (sp->tif->tif_dir.td_stripbytecount==NULL) | |
1977 | sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos; | |
1978 | else | |
1979 | { | |
1980 | if (sp->tif->tif_dir.td_stripbytecount == 0) { | |
1981 | TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip byte counts are missing"); | |
1982 | return(0); | |
1983 | } | |
1984 | sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile]; | |
1985 | if (sp->in_buffer_file_togo==0) | |
1986 | sp->in_buffer_file_pos=0; | |
1987 | else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size) | |
1988 | sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos; | |
1989 | } | |
1990 | } | |
1991 | sp->in_buffer_next_strile++; | |
1992 | } | |
1993 | break; | |
1994 | default: | |
1995 | return(0); | |
1996 | } | |
1997 | } while (1); | |
1998 | return(1); | |
1999 | } | |
2000 | ||
2001 | static int | |
2002 | OJPEGReadByte(OJPEGState* sp, uint8* byte) | |
2003 | { | |
2004 | if (sp->in_buffer_togo==0) | |
2005 | { | |
2006 | if (OJPEGReadBufferFill(sp)==0) | |
2007 | return(0); | |
2008 | assert(sp->in_buffer_togo>0); | |
2009 | } | |
2010 | *byte=*(sp->in_buffer_cur); | |
2011 | sp->in_buffer_cur++; | |
2012 | sp->in_buffer_togo--; | |
2013 | return(1); | |
2014 | } | |
2015 | ||
2016 | static int | |
2017 | OJPEGReadBytePeek(OJPEGState* sp, uint8* byte) | |
2018 | { | |
2019 | if (sp->in_buffer_togo==0) | |
2020 | { | |
2021 | if (OJPEGReadBufferFill(sp)==0) | |
2022 | return(0); | |
2023 | assert(sp->in_buffer_togo>0); | |
2024 | } | |
2025 | *byte=*(sp->in_buffer_cur); | |
2026 | return(1); | |
2027 | } | |
8414a40c VZ |
2028 | |
2029 | static void | |
80ed523f VZ |
2030 | OJPEGReadByteAdvance(OJPEGState* sp) |
2031 | { | |
2032 | assert(sp->in_buffer_togo>0); | |
2033 | sp->in_buffer_cur++; | |
2034 | sp->in_buffer_togo--; | |
2035 | } | |
2036 | ||
2037 | static int | |
2038 | OJPEGReadWord(OJPEGState* sp, uint16* word) | |
2039 | { | |
2040 | uint8 m; | |
2041 | if (OJPEGReadByte(sp,&m)==0) | |
2042 | return(0); | |
2043 | *word=(m<<8); | |
2044 | if (OJPEGReadByte(sp,&m)==0) | |
2045 | return(0); | |
2046 | *word|=m; | |
2047 | return(1); | |
2048 | } | |
2049 | ||
2050 | static int | |
2051 | OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem) | |
2052 | { | |
2053 | uint16 mlen; | |
2054 | uint8* mmem; | |
2055 | uint16 n; | |
2056 | assert(len>0); | |
2057 | mlen=len; | |
2058 | mmem=mem; | |
2059 | do | |
2060 | { | |
2061 | if (sp->in_buffer_togo==0) | |
2062 | { | |
2063 | if (OJPEGReadBufferFill(sp)==0) | |
2064 | return(0); | |
2065 | assert(sp->in_buffer_togo>0); | |
2066 | } | |
2067 | n=mlen; | |
2068 | if (n>sp->in_buffer_togo) | |
2069 | n=sp->in_buffer_togo; | |
2070 | _TIFFmemcpy(mmem,sp->in_buffer_cur,n); | |
2071 | sp->in_buffer_cur+=n; | |
2072 | sp->in_buffer_togo-=n; | |
2073 | mlen-=n; | |
2074 | mmem+=n; | |
2075 | } while(mlen>0); | |
2076 | return(1); | |
2077 | } | |
8414a40c VZ |
2078 | |
2079 | static void | |
80ed523f VZ |
2080 | OJPEGReadSkip(OJPEGState* sp, uint16 len) |
2081 | { | |
2082 | uint16 m; | |
2083 | uint16 n; | |
2084 | m=len; | |
2085 | n=m; | |
2086 | if (n>sp->in_buffer_togo) | |
2087 | n=sp->in_buffer_togo; | |
2088 | sp->in_buffer_cur+=n; | |
2089 | sp->in_buffer_togo-=n; | |
2090 | m-=n; | |
2091 | if (m>0) | |
2092 | { | |
2093 | assert(sp->in_buffer_togo==0); | |
2094 | n=m; | |
2095 | if ((uint64)n>sp->in_buffer_file_togo) | |
2096 | n=(uint16)sp->in_buffer_file_togo; | |
2097 | sp->in_buffer_file_pos+=n; | |
2098 | sp->in_buffer_file_togo-=n; | |
2099 | sp->in_buffer_file_pos_log=0; | |
2100 | /* we don't skip past jpeginterchangeformat/strile block... | |
2101 | * if that is asked from us, we're dealing with totally bazurk | |
2102 | * data anyway, and we've not seen this happening on any | |
2103 | * testfile, so we might as well likely cause some other | |
2104 | * meaningless error to be passed at some later time | |
2105 | */ | |
2106 | } | |
2107 | } | |
2108 | ||
2109 | static int | |
2110 | OJPEGWriteStream(TIFF* tif, void** mem, uint32* len) | |
2111 | { | |
2112 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
2113 | *len=0; | |
2114 | do | |
2115 | { | |
2116 | assert(sp->out_state<=ososEoi); | |
2117 | switch(sp->out_state) | |
2118 | { | |
2119 | case ososSoi: | |
2120 | OJPEGWriteStreamSoi(tif,mem,len); | |
2121 | break; | |
2122 | case ososQTable0: | |
2123 | OJPEGWriteStreamQTable(tif,0,mem,len); | |
2124 | break; | |
2125 | case ososQTable1: | |
2126 | OJPEGWriteStreamQTable(tif,1,mem,len); | |
2127 | break; | |
2128 | case ososQTable2: | |
2129 | OJPEGWriteStreamQTable(tif,2,mem,len); | |
2130 | break; | |
2131 | case ososQTable3: | |
2132 | OJPEGWriteStreamQTable(tif,3,mem,len); | |
2133 | break; | |
2134 | case ososDcTable0: | |
2135 | OJPEGWriteStreamDcTable(tif,0,mem,len); | |
2136 | break; | |
2137 | case ososDcTable1: | |
2138 | OJPEGWriteStreamDcTable(tif,1,mem,len); | |
2139 | break; | |
2140 | case ososDcTable2: | |
2141 | OJPEGWriteStreamDcTable(tif,2,mem,len); | |
2142 | break; | |
2143 | case ososDcTable3: | |
2144 | OJPEGWriteStreamDcTable(tif,3,mem,len); | |
2145 | break; | |
2146 | case ososAcTable0: | |
2147 | OJPEGWriteStreamAcTable(tif,0,mem,len); | |
2148 | break; | |
2149 | case ososAcTable1: | |
2150 | OJPEGWriteStreamAcTable(tif,1,mem,len); | |
2151 | break; | |
2152 | case ososAcTable2: | |
2153 | OJPEGWriteStreamAcTable(tif,2,mem,len); | |
2154 | break; | |
2155 | case ososAcTable3: | |
2156 | OJPEGWriteStreamAcTable(tif,3,mem,len); | |
2157 | break; | |
2158 | case ososDri: | |
2159 | OJPEGWriteStreamDri(tif,mem,len); | |
2160 | break; | |
2161 | case ososSof: | |
2162 | OJPEGWriteStreamSof(tif,mem,len); | |
2163 | break; | |
2164 | case ososSos: | |
2165 | OJPEGWriteStreamSos(tif,mem,len); | |
2166 | break; | |
2167 | case ososCompressed: | |
2168 | if (OJPEGWriteStreamCompressed(tif,mem,len)==0) | |
2169 | return(0); | |
2170 | break; | |
2171 | case ososRst: | |
2172 | OJPEGWriteStreamRst(tif,mem,len); | |
2173 | break; | |
2174 | case ososEoi: | |
2175 | OJPEGWriteStreamEoi(tif,mem,len); | |
2176 | break; | |
2177 | } | |
2178 | } while (*len==0); | |
2179 | return(1); | |
2180 | } | |
8414a40c VZ |
2181 | |
2182 | static void | |
80ed523f VZ |
2183 | OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len) |
2184 | { | |
2185 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
2186 | assert(OJPEG_BUFFER>=2); | |
2187 | sp->out_buffer[0]=255; | |
2188 | sp->out_buffer[1]=JPEG_MARKER_SOI; | |
2189 | *len=2; | |
2190 | *mem=(void*)sp->out_buffer; | |
2191 | sp->out_state++; | |
2192 | } | |
2193 | ||
2194 | static void | |
2195 | OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len) | |
2196 | { | |
2197 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
2198 | if (sp->qtable[table_index]!=0) | |
2199 | { | |
2200 | *mem=(void*)(sp->qtable[table_index]+sizeof(uint32)); | |
2201 | *len=*((uint32*)sp->qtable[table_index])-sizeof(uint32); | |
2202 | } | |
2203 | sp->out_state++; | |
2204 | } | |
2205 | ||
2206 | static void | |
2207 | OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len) | |
2208 | { | |
2209 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
2210 | if (sp->dctable[table_index]!=0) | |
2211 | { | |
2212 | *mem=(void*)(sp->dctable[table_index]+sizeof(uint32)); | |
2213 | *len=*((uint32*)sp->dctable[table_index])-sizeof(uint32); | |
2214 | } | |
2215 | sp->out_state++; | |
2216 | } | |
2217 | ||
2218 | static void | |
2219 | OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len) | |
2220 | { | |
2221 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
2222 | if (sp->actable[table_index]!=0) | |
2223 | { | |
2224 | *mem=(void*)(sp->actable[table_index]+sizeof(uint32)); | |
2225 | *len=*((uint32*)sp->actable[table_index])-sizeof(uint32); | |
2226 | } | |
2227 | sp->out_state++; | |
2228 | } | |
2229 | ||
2230 | static void | |
2231 | OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len) | |
2232 | { | |
2233 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
2234 | assert(OJPEG_BUFFER>=6); | |
2235 | if (sp->restart_interval!=0) | |
2236 | { | |
2237 | sp->out_buffer[0]=255; | |
2238 | sp->out_buffer[1]=JPEG_MARKER_DRI; | |
2239 | sp->out_buffer[2]=0; | |
2240 | sp->out_buffer[3]=4; | |
2241 | sp->out_buffer[4]=(sp->restart_interval>>8); | |
2242 | sp->out_buffer[5]=(sp->restart_interval&255); | |
2243 | *len=6; | |
2244 | *mem=(void*)sp->out_buffer; | |
2245 | } | |
2246 | sp->out_state++; | |
2247 | } | |
2248 | ||
2249 | static void | |
2250 | OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len) | |
2251 | { | |
2252 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
2253 | uint8 m; | |
2254 | assert(OJPEG_BUFFER>=2+8+sp->samples_per_pixel_per_plane*3); | |
2255 | assert(255>=8+sp->samples_per_pixel_per_plane*3); | |
2256 | sp->out_buffer[0]=255; | |
2257 | sp->out_buffer[1]=sp->sof_marker_id; | |
2258 | /* Lf */ | |
2259 | sp->out_buffer[2]=0; | |
2260 | sp->out_buffer[3]=8+sp->samples_per_pixel_per_plane*3; | |
2261 | /* P */ | |
2262 | sp->out_buffer[4]=8; | |
2263 | /* Y */ | |
2264 | sp->out_buffer[5]=(sp->sof_y>>8); | |
2265 | sp->out_buffer[6]=(sp->sof_y&255); | |
2266 | /* X */ | |
2267 | sp->out_buffer[7]=(sp->sof_x>>8); | |
2268 | sp->out_buffer[8]=(sp->sof_x&255); | |
2269 | /* Nf */ | |
2270 | sp->out_buffer[9]=sp->samples_per_pixel_per_plane; | |
2271 | for (m=0; m<sp->samples_per_pixel_per_plane; m++) | |
2272 | { | |
2273 | /* C */ | |
2274 | sp->out_buffer[10+m*3]=sp->sof_c[sp->plane_sample_offset+m]; | |
2275 | /* H and V */ | |
2276 | sp->out_buffer[10+m*3+1]=sp->sof_hv[sp->plane_sample_offset+m]; | |
2277 | /* Tq */ | |
2278 | sp->out_buffer[10+m*3+2]=sp->sof_tq[sp->plane_sample_offset+m]; | |
2279 | } | |
2280 | *len=10+sp->samples_per_pixel_per_plane*3; | |
2281 | *mem=(void*)sp->out_buffer; | |
2282 | sp->out_state++; | |
2283 | } | |
2284 | ||
2285 | static void | |
2286 | OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len) | |
2287 | { | |
2288 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
2289 | uint8 m; | |
2290 | assert(OJPEG_BUFFER>=2+6+sp->samples_per_pixel_per_plane*2); | |
2291 | assert(255>=6+sp->samples_per_pixel_per_plane*2); | |
2292 | sp->out_buffer[0]=255; | |
2293 | sp->out_buffer[1]=JPEG_MARKER_SOS; | |
2294 | /* Ls */ | |
2295 | sp->out_buffer[2]=0; | |
2296 | sp->out_buffer[3]=6+sp->samples_per_pixel_per_plane*2; | |
2297 | /* Ns */ | |
2298 | sp->out_buffer[4]=sp->samples_per_pixel_per_plane; | |
2299 | for (m=0; m<sp->samples_per_pixel_per_plane; m++) | |
2300 | { | |
2301 | /* Cs */ | |
2302 | sp->out_buffer[5+m*2]=sp->sos_cs[sp->plane_sample_offset+m]; | |
2303 | /* Td and Ta */ | |
2304 | sp->out_buffer[5+m*2+1]=sp->sos_tda[sp->plane_sample_offset+m]; | |
2305 | } | |
2306 | /* Ss */ | |
2307 | sp->out_buffer[5+sp->samples_per_pixel_per_plane*2]=0; | |
2308 | /* Se */ | |
2309 | sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+1]=63; | |
2310 | /* Ah and Al */ | |
2311 | sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+2]=0; | |
2312 | *len=8+sp->samples_per_pixel_per_plane*2; | |
2313 | *mem=(void*)sp->out_buffer; | |
2314 | sp->out_state++; | |
2315 | } | |
2316 | ||
2317 | static int | |
2318 | OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len) | |
2319 | { | |
2320 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
2321 | if (sp->in_buffer_togo==0) | |
2322 | { | |
2323 | if (OJPEGReadBufferFill(sp)==0) | |
2324 | return(0); | |
2325 | assert(sp->in_buffer_togo>0); | |
2326 | } | |
2327 | *len=sp->in_buffer_togo; | |
2328 | *mem=(void*)sp->in_buffer_cur; | |
2329 | sp->in_buffer_togo=0; | |
2330 | if (sp->in_buffer_file_togo==0) | |
2331 | { | |
2332 | switch(sp->in_buffer_source) | |
2333 | { | |
2334 | case osibsStrile: | |
2335 | if (sp->in_buffer_next_strile<sp->in_buffer_strile_count) | |
2336 | sp->out_state=ososRst; | |
2337 | else | |
2338 | sp->out_state=ososEoi; | |
2339 | break; | |
2340 | case osibsEof: | |
2341 | sp->out_state=ososEoi; | |
2342 | break; | |
2343 | default: | |
2344 | break; | |
2345 | } | |
2346 | } | |
2347 | return(1); | |
2348 | } | |
2349 | ||
2350 | static void | |
2351 | OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len) | |
2352 | { | |
2353 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
2354 | assert(OJPEG_BUFFER>=2); | |
2355 | sp->out_buffer[0]=255; | |
2356 | sp->out_buffer[1]=JPEG_MARKER_RST0+sp->restart_index; | |
2357 | sp->restart_index++; | |
2358 | if (sp->restart_index==8) | |
2359 | sp->restart_index=0; | |
2360 | *len=2; | |
2361 | *mem=(void*)sp->out_buffer; | |
2362 | sp->out_state=ososCompressed; | |
2363 | } | |
2364 | ||
2365 | static void | |
2366 | OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len) | |
2367 | { | |
2368 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
2369 | assert(OJPEG_BUFFER>=2); | |
2370 | sp->out_buffer[0]=255; | |
2371 | sp->out_buffer[1]=JPEG_MARKER_EOI; | |
2372 | *len=2; | |
2373 | *mem=(void*)sp->out_buffer; | |
2374 | } | |
2375 | ||
2376 | #ifndef LIBJPEG_ENCAP_EXTERNAL | |
2377 | static int | |
2378 | jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo) | |
2379 | { | |
2380 | return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_create_decompress(cinfo),1)); | |
2381 | } | |
2382 | #endif | |
2383 | ||
2384 | #ifndef LIBJPEG_ENCAP_EXTERNAL | |
2385 | static int | |
2386 | jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image) | |
2387 | { | |
2388 | return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_header(cinfo,require_image),1)); | |
2389 | } | |
2390 | #endif | |
2391 | ||
2392 | #ifndef LIBJPEG_ENCAP_EXTERNAL | |
2393 | static int | |
2394 | jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo) | |
2395 | { | |
2396 | return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_start_decompress(cinfo),1)); | |
2397 | } | |
2398 | #endif | |
2399 | ||
2400 | #ifndef LIBJPEG_ENCAP_EXTERNAL | |
2401 | static int | |
2402 | jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines) | |
2403 | { | |
2404 | return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_scanlines(cinfo,scanlines,max_lines),1)); | |
2405 | } | |
2406 | #endif | |
2407 | ||
2408 | #ifndef LIBJPEG_ENCAP_EXTERNAL | |
2409 | static int | |
2410 | jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines) | |
2411 | { | |
2412 | return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_raw_data(cinfo,data,max_lines),1)); | |
2413 | } | |
2414 | #endif | |
2415 | ||
2416 | #ifndef LIBJPEG_ENCAP_EXTERNAL | |
2417 | static void | |
2418 | jpeg_encap_unwind(TIFF* tif) | |
2419 | { | |
2420 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
2421 | LONGJMP(sp->exit_jmpbuf,1); | |
2422 | } | |
2423 | #endif | |
2424 | ||
2425 | static void | |
2426 | OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo) | |
2427 | { | |
2428 | char buffer[JMSG_LENGTH_MAX]; | |
2429 | (*cinfo->err->format_message)(cinfo,buffer); | |
2430 | TIFFWarningExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer); | |
2431 | } | |
2432 | ||
2433 | static void | |
2434 | OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo) | |
2435 | { | |
2436 | char buffer[JMSG_LENGTH_MAX]; | |
2437 | (*cinfo->err->format_message)(cinfo,buffer); | |
2438 | TIFFErrorExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer); | |
2439 | jpeg_encap_unwind((TIFF*)(cinfo->client_data)); | |
2440 | } | |
2441 | ||
2442 | static void | |
2443 | OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo) | |
2444 | { | |
2445 | (void)cinfo; | |
2446 | } | |
2447 | ||
94474c2e | 2448 | static wxjpeg_boolean |
80ed523f VZ |
2449 | OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo) |
2450 | { | |
2451 | TIFF* tif=(TIFF*)cinfo->client_data; | |
2452 | OJPEGState* sp=(OJPEGState*)tif->tif_data; | |
2453 | void* mem=0; | |
2454 | uint32 len=0U; | |
2455 | if (OJPEGWriteStream(tif,&mem,&len)==0) | |
2456 | { | |
2457 | TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Premature end of JPEG data"); | |
2458 | jpeg_encap_unwind(tif); | |
2459 | } | |
2460 | sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=len; | |
2461 | sp->libjpeg_jpeg_source_mgr.next_input_byte=mem; | |
2462 | return(1); | |
2463 | } | |
2464 | ||
2465 | static void | |
2466 | OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes) | |
2467 | { | |
2468 | TIFF* tif=(TIFF*)cinfo->client_data; | |
2469 | (void)num_bytes; | |
2470 | TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error"); | |
2471 | jpeg_encap_unwind(tif); | |
2472 | } | |
2473 | ||
94474c2e | 2474 | static wxjpeg_boolean |
80ed523f VZ |
2475 | OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired) |
2476 | { | |
2477 | TIFF* tif=(TIFF*)cinfo->client_data; | |
2478 | (void)desired; | |
2479 | TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error"); | |
2480 | jpeg_encap_unwind(tif); | |
2481 | return(0); | |
2482 | } | |
2483 | ||
2484 | static void | |
2485 | OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo) | |
2486 | { | |
2487 | (void)cinfo; | |
2488 | } | |
2489 | ||
2490 | #endif | |
8414a40c | 2491 | |
8414a40c | 2492 | |
80ed523f VZ |
2493 | /* |
2494 | * Local Variables: | |
2495 | * mode: c | |
2496 | * c-basic-offset: 8 | |
2497 | * fill-column: 78 | |
2498 | * End: | |
8414a40c | 2499 | */ |