]>
Commit | Line | Data |
---|---|---|
b47c832e RR |
1 | /* $Header$ */ |
2 | ||
3 | /* | |
4 | * Copyright (c) 1994-1997 Sam Leffler | |
5 | * Copyright (c) 1994-1997 Silicon Graphics, Inc. | |
6 | * | |
7 | * Permission to use, copy, modify, distribute, and sell this software and | |
8 | * its documentation for any purpose is hereby granted without fee, provided | |
9 | * that (i) the above copyright notices and this permission notice appear in | |
10 | * all copies of the software and related documentation, and (ii) the names of | |
11 | * Sam Leffler and Silicon Graphics may not be used in any advertising or | |
12 | * publicity relating to the software without the specific, prior written | |
13 | * permission of Sam Leffler and Silicon Graphics. | |
14 | * | |
15 | * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, | |
16 | * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY | |
17 | * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | |
18 | * | |
19 | * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR | |
20 | * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, | |
21 | * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
22 | * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF | |
23 | * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |
24 | * OF THIS SOFTWARE. | |
25 | */ | |
26 | ||
27 | #include "tiffiop.h" | |
28 | #ifdef JPEG_SUPPORT | |
29 | /* | |
30 | * TIFF Library | |
31 | * | |
32 | * JPEG Compression support per TIFF Technical Note #2 | |
33 | * (*not* per the original TIFF 6.0 spec). | |
34 | * | |
35 | * This file is simply an interface to the libjpeg library written by | |
36 | * the Independent JPEG Group. You need release 5 or later of the IJG | |
37 | * code, which you can find on the Internet at ftp.uu.net:/graphics/jpeg/. | |
38 | * | |
39 | * Contributed by Tom Lane <tgl@sss.pgh.pa.us>. | |
40 | */ | |
41 | #include <assert.h> | |
42 | #include <stdio.h> | |
43 | #include <setjmp.h> | |
44 | #include "jpeglib.h" | |
45 | #include "jerror.h" | |
46 | ||
47 | /* | |
48 | * On some machines it may be worthwhile to use _setjmp or sigsetjmp | |
49 | * in place of plain setjmp. These macros will make it easier. | |
50 | */ | |
51 | #define SETJMP(jbuf) setjmp(jbuf) | |
52 | #define LONGJMP(jbuf,code) longjmp(jbuf,code) | |
53 | #define JMP_BUF jmp_buf | |
54 | ||
55 | typedef struct jpeg_destination_mgr jpeg_destination_mgr; | |
56 | typedef struct jpeg_source_mgr jpeg_source_mgr; | |
57 | typedef struct jpeg_error_mgr jpeg_error_mgr; | |
58 | ||
59 | /* | |
60 | * State block for each open TIFF file using | |
61 | * libjpeg to do JPEG compression/decompression. | |
62 | * | |
63 | * libjpeg's visible state is either a jpeg_compress_struct | |
64 | * or jpeg_decompress_struct depending on which way we | |
65 | * are going. comm can be used to refer to the fields | |
66 | * which are common to both. | |
67 | * | |
68 | * NB: cinfo is required to be the first member of JPEGState, | |
69 | * so we can safely cast JPEGState* -> jpeg_xxx_struct* | |
70 | * and vice versa! | |
71 | */ | |
72 | typedef struct { | |
73 | union { | |
74 | struct jpeg_compress_struct c; | |
75 | struct jpeg_decompress_struct d; | |
76 | struct jpeg_common_struct comm; | |
77 | } cinfo; /* NB: must be first */ | |
78 | jpeg_error_mgr err; /* libjpeg error manager */ | |
79 | JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */ | |
80 | /* | |
81 | * The following two members could be a union, but | |
82 | * they're small enough that it's not worth the effort. | |
83 | */ | |
84 | jpeg_destination_mgr dest; /* data dest for compression */ | |
85 | jpeg_source_mgr src; /* data source for decompression */ | |
86 | /* private state */ | |
87 | TIFF* tif; /* back link needed by some code */ | |
88 | uint16 photometric; /* copy of PhotometricInterpretation */ | |
89 | uint16 h_sampling; /* luminance sampling factors */ | |
90 | uint16 v_sampling; | |
91 | tsize_t bytesperline; /* decompressed bytes per scanline */ | |
92 | /* pointers to intermediate buffers when processing downsampled data */ | |
93 | JSAMPARRAY ds_buffer[MAX_COMPONENTS]; | |
94 | int scancount; /* number of "scanlines" accumulated */ | |
95 | int samplesperclump; | |
96 | ||
97 | TIFFVGetMethod vgetparent; /* super-class method */ | |
98 | TIFFVSetMethod vsetparent; /* super-class method */ | |
99 | TIFFStripMethod defsparent; /* super-class method */ | |
100 | TIFFTileMethod deftparent; /* super-class method */ | |
101 | /* pseudo-tag fields */ | |
102 | void* jpegtables; /* JPEGTables tag value, or NULL */ | |
103 | uint32 jpegtables_length; /* number of bytes in same */ | |
104 | int jpegquality; /* Compression quality level */ | |
105 | int jpegcolormode; /* Auto RGB<=>YCbCr convert? */ | |
106 | int jpegtablesmode; /* What to put in JPEGTables */ | |
107 | } JPEGState; | |
108 | ||
109 | #define JState(tif) ((JPEGState*)(tif)->tif_data) | |
110 | ||
111 | static int JPEGDecode(TIFF*, tidata_t, tsize_t, tsample_t); | |
112 | static int JPEGDecodeRaw(TIFF*, tidata_t, tsize_t, tsample_t); | |
113 | static int JPEGEncode(TIFF*, tidata_t, tsize_t, tsample_t); | |
114 | static int JPEGEncodeRaw(TIFF*, tidata_t, tsize_t, tsample_t); | |
115 | ||
116 | #define FIELD_JPEGTABLES (FIELD_CODEC+0) | |
117 | ||
118 | static const TIFFFieldInfo jpegFieldInfo[] = { | |
119 | { TIFFTAG_JPEGTABLES, -1,-1, TIFF_UNDEFINED, FIELD_JPEGTABLES, | |
120 | FALSE, TRUE, "JPEGTables" }, | |
121 | { TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, FIELD_PSEUDO, | |
122 | TRUE, FALSE, "" }, | |
123 | { TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, FIELD_PSEUDO, | |
124 | FALSE, FALSE, "" }, | |
125 | { TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, FIELD_PSEUDO, | |
126 | FALSE, FALSE, "" }, | |
127 | }; | |
128 | #define N(a) (sizeof (a) / sizeof (a[0])) | |
129 | ||
130 | /* | |
131 | * libjpeg interface layer. | |
132 | * | |
133 | * We use setjmp/longjmp to return control to libtiff | |
134 | * when a fatal error is encountered within the JPEG | |
135 | * library. We also direct libjpeg error and warning | |
136 | * messages through the appropriate libtiff handlers. | |
137 | */ | |
138 | ||
139 | /* | |
140 | * Error handling routines (these replace corresponding | |
141 | * IJG routines from jerror.c). These are used for both | |
142 | * compression and decompression. | |
143 | */ | |
144 | static void | |
145 | TIFFjpeg_error_exit(j_common_ptr cinfo) | |
146 | { | |
147 | JPEGState *sp = (JPEGState *) cinfo; /* NB: cinfo assumed first */ | |
148 | char buffer[JMSG_LENGTH_MAX]; | |
149 | ||
150 | (*cinfo->err->format_message) (cinfo, buffer); | |
151 | TIFFError("JPEGLib", buffer); /* display the error message */ | |
152 | jpeg_abort(cinfo); /* clean up libjpeg state */ | |
153 | LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ | |
154 | } | |
155 | ||
156 | /* | |
157 | * This routine is invoked only for warning messages, | |
158 | * since error_exit does its own thing and trace_level | |
159 | * is never set > 0. | |
160 | */ | |
161 | static void | |
162 | TIFFjpeg_output_message(j_common_ptr cinfo) | |
163 | { | |
164 | char buffer[JMSG_LENGTH_MAX]; | |
165 | ||
166 | (*cinfo->err->format_message) (cinfo, buffer); | |
167 | TIFFWarning("JPEGLib", buffer); | |
168 | } | |
169 | ||
170 | /* | |
171 | * Interface routines. This layer of routines exists | |
172 | * primarily to limit side-effects from using setjmp. | |
173 | * Also, normal/error returns are converted into return | |
174 | * values per libtiff practice. | |
175 | */ | |
176 | #define CALLJPEG(sp, fail, op) (SETJMP((sp)->exit_jmpbuf) ? (fail) : (op)) | |
177 | #define CALLVJPEG(sp, op) CALLJPEG(sp, 0, ((op),1)) | |
178 | ||
179 | static int | |
180 | TIFFjpeg_create_compress(JPEGState* sp) | |
181 | { | |
182 | /* initialize JPEG error handling */ | |
183 | sp->cinfo.c.err = jpeg_std_error(&sp->err); | |
184 | sp->err.error_exit = TIFFjpeg_error_exit; | |
185 | sp->err.output_message = TIFFjpeg_output_message; | |
186 | ||
187 | return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c)); | |
188 | } | |
189 | ||
190 | static int | |
191 | TIFFjpeg_create_decompress(JPEGState* sp) | |
192 | { | |
193 | /* initialize JPEG error handling */ | |
194 | sp->cinfo.d.err = jpeg_std_error(&sp->err); | |
195 | sp->err.error_exit = TIFFjpeg_error_exit; | |
196 | sp->err.output_message = TIFFjpeg_output_message; | |
197 | ||
198 | return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d)); | |
199 | } | |
200 | ||
201 | static int | |
202 | TIFFjpeg_set_defaults(JPEGState* sp) | |
203 | { | |
204 | return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c)); | |
205 | } | |
206 | ||
207 | static int | |
208 | TIFFjpeg_set_colorspace(JPEGState* sp, J_COLOR_SPACE colorspace) | |
209 | { | |
210 | return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace)); | |
211 | } | |
212 | ||
213 | static int | |
214 | TIFFjpeg_set_quality(JPEGState* sp, int quality, boolean force_baseline) | |
215 | { | |
216 | return CALLVJPEG(sp, | |
217 | jpeg_set_quality(&sp->cinfo.c, quality, force_baseline)); | |
218 | } | |
219 | ||
220 | static int | |
221 | TIFFjpeg_suppress_tables(JPEGState* sp, boolean suppress) | |
222 | { | |
223 | return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress)); | |
224 | } | |
225 | ||
226 | static int | |
227 | TIFFjpeg_start_compress(JPEGState* sp, boolean write_all_tables) | |
228 | { | |
229 | return CALLVJPEG(sp, | |
230 | jpeg_start_compress(&sp->cinfo.c, write_all_tables)); | |
231 | } | |
232 | ||
233 | static int | |
234 | TIFFjpeg_write_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int num_lines) | |
235 | { | |
236 | return CALLJPEG(sp, -1, (int) jpeg_write_scanlines(&sp->cinfo.c, | |
237 | scanlines, (JDIMENSION) num_lines)); | |
238 | } | |
239 | ||
240 | static int | |
241 | TIFFjpeg_write_raw_data(JPEGState* sp, JSAMPIMAGE data, int num_lines) | |
242 | { | |
243 | return CALLJPEG(sp, -1, (int) jpeg_write_raw_data(&sp->cinfo.c, | |
244 | data, (JDIMENSION) num_lines)); | |
245 | } | |
246 | ||
247 | static int | |
248 | TIFFjpeg_finish_compress(JPEGState* sp) | |
249 | { | |
250 | return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c)); | |
251 | } | |
252 | ||
253 | static int | |
254 | TIFFjpeg_write_tables(JPEGState* sp) | |
255 | { | |
256 | return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c)); | |
257 | } | |
258 | ||
259 | static int | |
260 | TIFFjpeg_read_header(JPEGState* sp, boolean require_image) | |
261 | { | |
262 | return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image)); | |
263 | } | |
264 | ||
265 | static int | |
266 | TIFFjpeg_start_decompress(JPEGState* sp) | |
267 | { | |
268 | return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d)); | |
269 | } | |
270 | ||
271 | static int | |
272 | TIFFjpeg_read_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int max_lines) | |
273 | { | |
274 | return CALLJPEG(sp, -1, (int) jpeg_read_scanlines(&sp->cinfo.d, | |
275 | scanlines, (JDIMENSION) max_lines)); | |
276 | } | |
277 | ||
278 | static int | |
279 | TIFFjpeg_read_raw_data(JPEGState* sp, JSAMPIMAGE data, int max_lines) | |
280 | { | |
281 | return CALLJPEG(sp, -1, (int) jpeg_read_raw_data(&sp->cinfo.d, | |
282 | data, (JDIMENSION) max_lines)); | |
283 | } | |
284 | ||
285 | static int | |
286 | TIFFjpeg_finish_decompress(JPEGState* sp) | |
287 | { | |
288 | return CALLJPEG(sp, -1, (int) jpeg_finish_decompress(&sp->cinfo.d)); | |
289 | } | |
290 | ||
291 | static int | |
292 | TIFFjpeg_abort(JPEGState* sp) | |
293 | { | |
294 | return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm)); | |
295 | } | |
296 | ||
297 | static int | |
298 | TIFFjpeg_destroy(JPEGState* sp) | |
299 | { | |
300 | return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm)); | |
301 | } | |
302 | ||
303 | static JSAMPARRAY | |
304 | TIFFjpeg_alloc_sarray(JPEGState* sp, int pool_id, | |
305 | JDIMENSION samplesperrow, JDIMENSION numrows) | |
306 | { | |
307 | return CALLJPEG(sp, (JSAMPARRAY) NULL, | |
308 | (*sp->cinfo.comm.mem->alloc_sarray) | |
309 | (&sp->cinfo.comm, pool_id, samplesperrow, numrows)); | |
310 | } | |
311 | ||
312 | /* | |
313 | * JPEG library destination data manager. | |
314 | * These routines direct compressed data from libjpeg into the | |
315 | * libtiff output buffer. | |
316 | */ | |
317 | ||
318 | static void | |
319 | std_init_destination(j_compress_ptr cinfo) | |
320 | { | |
321 | JPEGState* sp = (JPEGState*) cinfo; | |
322 | TIFF* tif = sp->tif; | |
323 | ||
324 | sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata; | |
325 | sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize; | |
326 | } | |
327 | ||
328 | static boolean | |
329 | std_empty_output_buffer(j_compress_ptr cinfo) | |
330 | { | |
331 | JPEGState* sp = (JPEGState*) cinfo; | |
332 | TIFF* tif = sp->tif; | |
333 | ||
334 | /* the entire buffer has been filled */ | |
335 | tif->tif_rawcc = tif->tif_rawdatasize; | |
336 | TIFFFlushData1(tif); | |
337 | sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata; | |
338 | sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize; | |
339 | ||
340 | return (TRUE); | |
341 | } | |
342 | ||
343 | static void | |
344 | std_term_destination(j_compress_ptr cinfo) | |
345 | { | |
346 | JPEGState* sp = (JPEGState*) cinfo; | |
347 | TIFF* tif = sp->tif; | |
348 | ||
349 | tif->tif_rawcp = (tidata_t) sp->dest.next_output_byte; | |
350 | tif->tif_rawcc = | |
351 | tif->tif_rawdatasize - (tsize_t) sp->dest.free_in_buffer; | |
352 | /* NB: libtiff does the final buffer flush */ | |
353 | } | |
354 | ||
355 | static void | |
356 | TIFFjpeg_data_dest(JPEGState* sp, TIFF* tif) | |
357 | { | |
358 | (void) tif; | |
359 | sp->cinfo.c.dest = &sp->dest; | |
360 | sp->dest.init_destination = std_init_destination; | |
361 | sp->dest.empty_output_buffer = std_empty_output_buffer; | |
362 | sp->dest.term_destination = std_term_destination; | |
363 | } | |
364 | ||
365 | /* | |
366 | * Alternate destination manager for outputting to JPEGTables field. | |
367 | */ | |
368 | ||
369 | static void | |
370 | tables_init_destination(j_compress_ptr cinfo) | |
371 | { | |
372 | JPEGState* sp = (JPEGState*) cinfo; | |
373 | ||
374 | /* while building, jpegtables_length is allocated buffer size */ | |
375 | sp->dest.next_output_byte = (JOCTET*) sp->jpegtables; | |
376 | sp->dest.free_in_buffer = (size_t) sp->jpegtables_length; | |
377 | } | |
378 | ||
379 | static boolean | |
380 | tables_empty_output_buffer(j_compress_ptr cinfo) | |
381 | { | |
382 | JPEGState* sp = (JPEGState*) cinfo; | |
383 | void* newbuf; | |
384 | ||
385 | /* the entire buffer has been filled; enlarge it by 1000 bytes */ | |
386 | newbuf = _TIFFrealloc((tdata_t) sp->jpegtables, | |
387 | (tsize_t) (sp->jpegtables_length + 1000)); | |
388 | if (newbuf == NULL) | |
389 | ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100); | |
390 | sp->dest.next_output_byte = (JOCTET*) newbuf + sp->jpegtables_length; | |
391 | sp->dest.free_in_buffer = (size_t) 1000; | |
392 | sp->jpegtables = newbuf; | |
393 | sp->jpegtables_length += 1000; | |
394 | return (TRUE); | |
395 | } | |
396 | ||
397 | static void | |
398 | tables_term_destination(j_compress_ptr cinfo) | |
399 | { | |
400 | JPEGState* sp = (JPEGState*) cinfo; | |
401 | ||
402 | /* set tables length to number of bytes actually emitted */ | |
403 | sp->jpegtables_length -= sp->dest.free_in_buffer; | |
404 | } | |
405 | ||
406 | static int | |
407 | TIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif) | |
408 | { | |
409 | (void) tif; | |
410 | /* | |
411 | * Allocate a working buffer for building tables. | |
412 | * Initial size is 1000 bytes, which is usually adequate. | |
413 | */ | |
414 | if (sp->jpegtables) | |
415 | _TIFFfree(sp->jpegtables); | |
416 | sp->jpegtables_length = 1000; | |
417 | sp->jpegtables = (void*) _TIFFmalloc((tsize_t) sp->jpegtables_length); | |
418 | if (sp->jpegtables == NULL) { | |
419 | sp->jpegtables_length = 0; | |
420 | TIFFError("TIFFjpeg_tables_dest", "No space for JPEGTables"); | |
421 | return (0); | |
422 | } | |
423 | sp->cinfo.c.dest = &sp->dest; | |
424 | sp->dest.init_destination = tables_init_destination; | |
425 | sp->dest.empty_output_buffer = tables_empty_output_buffer; | |
426 | sp->dest.term_destination = tables_term_destination; | |
427 | return (1); | |
428 | } | |
429 | ||
430 | /* | |
431 | * JPEG library source data manager. | |
432 | * These routines supply compressed data to libjpeg. | |
433 | */ | |
434 | ||
435 | static void | |
436 | std_init_source(j_decompress_ptr cinfo) | |
437 | { | |
438 | JPEGState* sp = (JPEGState*) cinfo; | |
439 | TIFF* tif = sp->tif; | |
440 | ||
441 | sp->src.next_input_byte = (const JOCTET*) tif->tif_rawdata; | |
442 | sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc; | |
443 | } | |
444 | ||
445 | static boolean | |
446 | std_fill_input_buffer(j_decompress_ptr cinfo) | |
447 | { | |
448 | JPEGState* sp = (JPEGState* ) cinfo; | |
449 | static const JOCTET dummy_EOI[2] = { 0xFF, JPEG_EOI }; | |
450 | ||
451 | /* | |
452 | * Should never get here since entire strip/tile is | |
453 | * read into memory before the decompressor is called, | |
454 | * and thus was supplied by init_source. | |
455 | */ | |
456 | WARNMS(cinfo, JWRN_JPEG_EOF); | |
457 | /* insert a fake EOI marker */ | |
458 | sp->src.next_input_byte = dummy_EOI; | |
459 | sp->src.bytes_in_buffer = 2; | |
460 | return (TRUE); | |
461 | } | |
462 | ||
463 | static void | |
464 | std_skip_input_data(j_decompress_ptr cinfo, long num_bytes) | |
465 | { | |
466 | JPEGState* sp = (JPEGState*) cinfo; | |
467 | ||
468 | if (num_bytes > 0) { | |
469 | if (num_bytes > (long) sp->src.bytes_in_buffer) { | |
470 | /* oops, buffer overrun */ | |
471 | (void) std_fill_input_buffer(cinfo); | |
472 | } else { | |
473 | sp->src.next_input_byte += (size_t) num_bytes; | |
474 | sp->src.bytes_in_buffer -= (size_t) num_bytes; | |
475 | } | |
476 | } | |
477 | } | |
478 | ||
479 | static void | |
480 | std_term_source(j_decompress_ptr cinfo) | |
481 | { | |
482 | /* No work necessary here */ | |
483 | /* Or must we update tif->tif_rawcp, tif->tif_rawcc ??? */ | |
484 | /* (if so, need empty tables_term_source!) */ | |
485 | (void) cinfo; | |
486 | } | |
487 | ||
488 | static void | |
489 | TIFFjpeg_data_src(JPEGState* sp, TIFF* tif) | |
490 | { | |
491 | (void) tif; | |
492 | sp->cinfo.d.src = &sp->src; | |
493 | sp->src.init_source = std_init_source; | |
494 | sp->src.fill_input_buffer = std_fill_input_buffer; | |
495 | sp->src.skip_input_data = std_skip_input_data; | |
496 | sp->src.resync_to_restart = jpeg_resync_to_restart; | |
497 | sp->src.term_source = std_term_source; | |
498 | sp->src.bytes_in_buffer = 0; /* for safety */ | |
499 | sp->src.next_input_byte = NULL; | |
500 | } | |
501 | ||
502 | /* | |
503 | * Alternate source manager for reading from JPEGTables. | |
504 | * We can share all the code except for the init routine. | |
505 | */ | |
506 | ||
507 | static void | |
508 | tables_init_source(j_decompress_ptr cinfo) | |
509 | { | |
510 | JPEGState* sp = (JPEGState*) cinfo; | |
511 | ||
512 | sp->src.next_input_byte = (const JOCTET*) sp->jpegtables; | |
513 | sp->src.bytes_in_buffer = (size_t) sp->jpegtables_length; | |
514 | } | |
515 | ||
516 | static void | |
517 | TIFFjpeg_tables_src(JPEGState* sp, TIFF* tif) | |
518 | { | |
519 | TIFFjpeg_data_src(sp, tif); | |
520 | sp->src.init_source = tables_init_source; | |
521 | } | |
522 | ||
523 | /* | |
524 | * Allocate downsampled-data buffers needed for downsampled I/O. | |
525 | * We use values computed in jpeg_start_compress or jpeg_start_decompress. | |
526 | * We use libjpeg's allocator so that buffers will be released automatically | |
527 | * when done with strip/tile. | |
528 | * This is also a handy place to compute samplesperclump, bytesperline. | |
529 | */ | |
530 | static int | |
531 | alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info, | |
532 | int num_components) | |
533 | { | |
534 | JPEGState* sp = JState(tif); | |
535 | int ci; | |
536 | jpeg_component_info* compptr; | |
537 | JSAMPARRAY buf; | |
538 | int samples_per_clump = 0; | |
539 | ||
540 | for (ci = 0, compptr = comp_info; ci < num_components; | |
541 | ci++, compptr++) { | |
542 | samples_per_clump += compptr->h_samp_factor * | |
543 | compptr->v_samp_factor; | |
544 | buf = TIFFjpeg_alloc_sarray(sp, JPOOL_IMAGE, | |
545 | compptr->width_in_blocks * DCTSIZE, | |
546 | (JDIMENSION) (compptr->v_samp_factor*DCTSIZE)); | |
547 | if (buf == NULL) | |
548 | return (0); | |
549 | sp->ds_buffer[ci] = buf; | |
550 | } | |
551 | sp->samplesperclump = samples_per_clump; | |
552 | /* Cb,Cr both have sampling factors 1 */ | |
553 | /* so downsampled width of Cb is # of clumps per line */ | |
554 | sp->bytesperline = sizeof(JSAMPLE) * samples_per_clump * | |
555 | comp_info[1].downsampled_width; | |
556 | return (1); | |
557 | } | |
558 | ||
559 | ||
560 | /* | |
561 | * JPEG Decoding. | |
562 | */ | |
563 | ||
564 | static int | |
565 | JPEGSetupDecode(TIFF* tif) | |
566 | { | |
567 | JPEGState* sp = JState(tif); | |
568 | TIFFDirectory *td = &tif->tif_dir; | |
569 | ||
570 | assert(sp != NULL); | |
571 | assert(sp->cinfo.comm.is_decompressor); | |
572 | ||
573 | /* Read JPEGTables if it is present */ | |
574 | if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) { | |
575 | TIFFjpeg_tables_src(sp, tif); | |
576 | if(TIFFjpeg_read_header(sp,FALSE) != JPEG_HEADER_TABLES_ONLY) { | |
577 | TIFFError("JPEGSetupDecode", "Bogus JPEGTables field"); | |
578 | return (0); | |
579 | } | |
580 | } | |
581 | ||
582 | /* Grab parameters that are same for all strips/tiles */ | |
583 | sp->photometric = td->td_photometric; | |
584 | switch (sp->photometric) { | |
585 | case PHOTOMETRIC_YCBCR: | |
586 | sp->h_sampling = td->td_ycbcrsubsampling[0]; | |
587 | sp->v_sampling = td->td_ycbcrsubsampling[1]; | |
588 | break; | |
589 | default: | |
590 | /* TIFF 6.0 forbids subsampling of all other color spaces */ | |
591 | sp->h_sampling = 1; | |
592 | sp->v_sampling = 1; | |
593 | break; | |
594 | } | |
595 | ||
596 | /* Set up for reading normal data */ | |
597 | TIFFjpeg_data_src(sp, tif); | |
598 | tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */ | |
599 | return (1); | |
600 | } | |
601 | ||
602 | /* | |
603 | * Set up for decoding a strip or tile. | |
604 | */ | |
605 | static int | |
606 | JPEGPreDecode(TIFF* tif, tsample_t s) | |
607 | { | |
608 | JPEGState *sp = JState(tif); | |
609 | TIFFDirectory *td = &tif->tif_dir; | |
610 | static const char module[] = "JPEGPreDecode"; | |
611 | uint32 segment_width, segment_height; | |
612 | int downsampled_output; | |
613 | int ci; | |
614 | ||
615 | assert(sp != NULL); | |
616 | assert(sp->cinfo.comm.is_decompressor); | |
617 | /* | |
618 | * Reset decoder state from any previous strip/tile, | |
619 | * in case application didn't read the whole strip. | |
620 | */ | |
621 | if (!TIFFjpeg_abort(sp)) | |
622 | return (0); | |
623 | /* | |
624 | * Read the header for this strip/tile. | |
625 | */ | |
626 | if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK) | |
627 | return (0); | |
628 | /* | |
629 | * Check image parameters and set decompression parameters. | |
630 | */ | |
631 | if (isTiled(tif)) { | |
632 | segment_width = td->td_tilewidth; | |
633 | segment_height = td->td_tilelength; | |
634 | sp->bytesperline = TIFFTileRowSize(tif); | |
635 | } else { | |
636 | segment_width = td->td_imagewidth; | |
637 | segment_height = td->td_imagelength - tif->tif_row; | |
638 | if (segment_height > td->td_rowsperstrip) | |
639 | segment_height = td->td_rowsperstrip; | |
640 | sp->bytesperline = TIFFScanlineSize(tif); | |
641 | } | |
642 | if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { | |
643 | /* | |
644 | * For PC 2, scale down the expected strip/tile size | |
645 | * to match a downsampled component | |
646 | */ | |
647 | segment_width = TIFFhowmany(segment_width, sp->h_sampling); | |
648 | segment_height = TIFFhowmany(segment_height, sp->v_sampling); | |
649 | } | |
650 | if (sp->cinfo.d.image_width != segment_width || | |
651 | sp->cinfo.d.image_height != segment_height) { | |
652 | TIFFError(module, "Improper JPEG strip/tile size"); | |
653 | return (0); | |
654 | } | |
655 | if (sp->cinfo.d.num_components != | |
656 | (td->td_planarconfig == PLANARCONFIG_CONTIG ? | |
657 | td->td_samplesperpixel : 1)) { | |
658 | TIFFError(module, "Improper JPEG component count"); | |
659 | return (0); | |
660 | } | |
661 | if (sp->cinfo.d.data_precision != td->td_bitspersample) { | |
662 | TIFFError(module, "Improper JPEG data precision"); | |
663 | return (0); | |
664 | } | |
665 | if (td->td_planarconfig == PLANARCONFIG_CONTIG) { | |
666 | /* Component 0 should have expected sampling factors */ | |
667 | if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling || | |
668 | sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) { | |
669 | TIFFError(module, "Improper JPEG sampling factors"); | |
670 | return (0); | |
671 | } | |
672 | /* Rest should have sampling factors 1,1 */ | |
673 | for (ci = 1; ci < sp->cinfo.d.num_components; ci++) { | |
674 | if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 || | |
675 | sp->cinfo.d.comp_info[ci].v_samp_factor != 1) { | |
676 | TIFFError(module, "Improper JPEG sampling factors"); | |
677 | return (0); | |
678 | } | |
679 | } | |
680 | } else { | |
681 | /* PC 2's single component should have sampling factors 1,1 */ | |
682 | if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 || | |
683 | sp->cinfo.d.comp_info[0].v_samp_factor != 1) { | |
684 | TIFFError(module, "Improper JPEG sampling factors"); | |
685 | return (0); | |
686 | } | |
687 | } | |
688 | downsampled_output = FALSE; | |
689 | if (td->td_planarconfig == PLANARCONFIG_CONTIG && | |
690 | sp->photometric == PHOTOMETRIC_YCBCR && | |
691 | sp->jpegcolormode == JPEGCOLORMODE_RGB) { | |
692 | /* Convert YCbCr to RGB */ | |
693 | sp->cinfo.d.jpeg_color_space = JCS_YCbCr; | |
694 | sp->cinfo.d.out_color_space = JCS_RGB; | |
695 | } else { | |
696 | /* Suppress colorspace handling */ | |
697 | sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN; | |
698 | sp->cinfo.d.out_color_space = JCS_UNKNOWN; | |
699 | if (td->td_planarconfig == PLANARCONFIG_CONTIG && | |
700 | (sp->h_sampling != 1 || sp->v_sampling != 1)) | |
701 | downsampled_output = TRUE; | |
702 | /* XXX what about up-sampling? */ | |
703 | } | |
704 | if (downsampled_output) { | |
705 | /* Need to use raw-data interface to libjpeg */ | |
706 | sp->cinfo.d.raw_data_out = TRUE; | |
707 | tif->tif_decoderow = JPEGDecodeRaw; | |
708 | tif->tif_decodestrip = JPEGDecodeRaw; | |
709 | tif->tif_decodetile = JPEGDecodeRaw; | |
710 | } else { | |
711 | /* Use normal interface to libjpeg */ | |
712 | sp->cinfo.d.raw_data_out = FALSE; | |
713 | tif->tif_decoderow = JPEGDecode; | |
714 | tif->tif_decodestrip = JPEGDecode; | |
715 | tif->tif_decodetile = JPEGDecode; | |
716 | } | |
717 | /* Start JPEG decompressor */ | |
718 | if (!TIFFjpeg_start_decompress(sp)) | |
719 | return (0); | |
720 | /* Allocate downsampled-data buffers if needed */ | |
721 | if (downsampled_output) { | |
722 | if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info, | |
723 | sp->cinfo.d.num_components)) | |
724 | return (0); | |
725 | sp->scancount = DCTSIZE; /* mark buffer empty */ | |
726 | } | |
727 | return (1); | |
728 | } | |
729 | ||
730 | /* | |
731 | * Decode a chunk of pixels. | |
732 | * "Standard" case: returned data is not downsampled. | |
733 | */ | |
734 | static int | |
735 | JPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) | |
736 | { | |
737 | JPEGState *sp = JState(tif); | |
738 | tsize_t nrows; | |
739 | JSAMPROW bufptr[1]; | |
740 | ||
741 | (void) s; | |
742 | assert(sp != NULL); | |
743 | /* data is expected to be read in multiples of a scanline */ | |
744 | nrows = cc / sp->bytesperline; | |
745 | if (cc % sp->bytesperline) | |
746 | TIFFWarning(tif->tif_name, "fractional scanline not read"); | |
747 | ||
748 | while (nrows-- > 0) { | |
749 | bufptr[0] = (JSAMPROW) buf; | |
750 | if (TIFFjpeg_read_scanlines(sp, bufptr, 1) != 1) | |
751 | return (0); | |
752 | if (nrows > 0) | |
753 | tif->tif_row++; | |
754 | buf += sp->bytesperline; | |
755 | } | |
756 | /* Close down the decompressor if we've finished the strip or tile. */ | |
757 | if (sp->cinfo.d.output_scanline == sp->cinfo.d.output_height) { | |
758 | if (TIFFjpeg_finish_decompress(sp) != TRUE) | |
759 | return (0); | |
760 | } | |
761 | return (1); | |
762 | } | |
763 | ||
764 | /* | |
765 | * Decode a chunk of pixels. | |
766 | * Returned data is downsampled per sampling factors. | |
767 | */ | |
768 | static int | |
769 | JPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) | |
770 | { | |
771 | JPEGState *sp = JState(tif); | |
772 | JSAMPLE* inptr; | |
773 | JSAMPLE* outptr; | |
774 | tsize_t nrows; | |
775 | JDIMENSION clumps_per_line, nclump; | |
776 | int clumpoffset, ci, xpos, ypos; | |
777 | jpeg_component_info* compptr; | |
778 | int samples_per_clump = sp->samplesperclump; | |
779 | ||
780 | (void) s; | |
781 | assert(sp != NULL); | |
782 | /* data is expected to be read in multiples of a scanline */ | |
783 | nrows = cc / sp->bytesperline; | |
784 | if (cc % sp->bytesperline) | |
785 | TIFFWarning(tif->tif_name, "fractional scanline not read"); | |
786 | ||
787 | /* Cb,Cr both have sampling factors 1, so this is correct */ | |
788 | clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width; | |
789 | ||
790 | while (nrows-- > 0) { | |
791 | /* Reload downsampled-data buffer if needed */ | |
792 | if (sp->scancount >= DCTSIZE) { | |
793 | int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE; | |
794 | if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n) | |
795 | return (0); | |
796 | sp->scancount = 0; | |
797 | /* Close down the decompressor if done. */ | |
798 | if (sp->cinfo.d.output_scanline >= | |
799 | sp->cinfo.d.output_height) { | |
800 | if (TIFFjpeg_finish_decompress(sp) != TRUE) | |
801 | return (0); | |
802 | } | |
803 | } | |
804 | /* | |
805 | * Fastest way to unseparate the data is to make one pass | |
806 | * over the scanline for each row of each component. | |
807 | */ | |
808 | clumpoffset = 0; /* first sample in clump */ | |
809 | for (ci = 0, compptr = sp->cinfo.d.comp_info; | |
810 | ci < sp->cinfo.d.num_components; | |
811 | ci++, compptr++) { | |
812 | int hsamp = compptr->h_samp_factor; | |
813 | int vsamp = compptr->v_samp_factor; | |
814 | for (ypos = 0; ypos < vsamp; ypos++) { | |
815 | inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos]; | |
816 | outptr = ((JSAMPLE*) buf) + clumpoffset; | |
817 | if (hsamp == 1) { | |
818 | /* fast path for at least Cb and Cr */ | |
819 | for (nclump = clumps_per_line; nclump-- > 0; ) { | |
820 | outptr[0] = *inptr++; | |
821 | outptr += samples_per_clump; | |
822 | } | |
823 | } else { | |
824 | /* general case */ | |
825 | for (nclump = clumps_per_line; nclump-- > 0; ) { | |
826 | for (xpos = 0; xpos < hsamp; xpos++) | |
827 | outptr[xpos] = *inptr++; | |
828 | outptr += samples_per_clump; | |
829 | } | |
830 | } | |
831 | clumpoffset += hsamp; | |
832 | } | |
833 | } | |
834 | sp->scancount++; | |
835 | if (nrows > 0) | |
836 | tif->tif_row++; | |
837 | buf += sp->bytesperline; | |
838 | } | |
839 | return (1); | |
840 | } | |
841 | ||
842 | ||
843 | /* | |
844 | * JPEG Encoding. | |
845 | */ | |
846 | ||
847 | static void | |
848 | unsuppress_quant_table (JPEGState* sp, int tblno) | |
849 | { | |
850 | JQUANT_TBL* qtbl; | |
851 | ||
852 | if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) | |
853 | qtbl->sent_table = FALSE; | |
854 | } | |
855 | ||
856 | static void | |
857 | unsuppress_huff_table (JPEGState* sp, int tblno) | |
858 | { | |
859 | JHUFF_TBL* htbl; | |
860 | ||
861 | if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) | |
862 | htbl->sent_table = FALSE; | |
863 | if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) | |
864 | htbl->sent_table = FALSE; | |
865 | } | |
866 | ||
867 | static int | |
868 | prepare_JPEGTables(TIFF* tif) | |
869 | { | |
870 | JPEGState* sp = JState(tif); | |
871 | ||
872 | /* Initialize quant tables for current quality setting */ | |
873 | if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) | |
874 | return (0); | |
875 | /* Mark only the tables we want for output */ | |
876 | /* NB: chrominance tables are currently used only with YCbCr */ | |
877 | if (!TIFFjpeg_suppress_tables(sp, TRUE)) | |
878 | return (0); | |
879 | if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) { | |
880 | unsuppress_quant_table(sp, 0); | |
881 | if (sp->photometric == PHOTOMETRIC_YCBCR) | |
882 | unsuppress_quant_table(sp, 1); | |
883 | } | |
884 | if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) { | |
885 | unsuppress_huff_table(sp, 0); | |
886 | if (sp->photometric == PHOTOMETRIC_YCBCR) | |
887 | unsuppress_huff_table(sp, 1); | |
888 | } | |
889 | /* Direct libjpeg output into jpegtables */ | |
890 | if (!TIFFjpeg_tables_dest(sp, tif)) | |
891 | return (0); | |
892 | /* Emit tables-only datastream */ | |
893 | if (!TIFFjpeg_write_tables(sp)) | |
894 | return (0); | |
895 | ||
896 | return (1); | |
897 | } | |
898 | ||
899 | static int | |
900 | JPEGSetupEncode(TIFF* tif) | |
901 | { | |
902 | JPEGState* sp = JState(tif); | |
903 | TIFFDirectory *td = &tif->tif_dir; | |
904 | static const char module[] = "JPEGSetupEncode"; | |
905 | ||
906 | assert(sp != NULL); | |
907 | assert(!sp->cinfo.comm.is_decompressor); | |
908 | ||
909 | /* | |
910 | * Initialize all JPEG parameters to default values. | |
911 | * Note that jpeg_set_defaults needs legal values for | |
912 | * in_color_space and input_components. | |
913 | */ | |
914 | sp->cinfo.c.in_color_space = JCS_UNKNOWN; | |
915 | sp->cinfo.c.input_components = 1; | |
916 | if (!TIFFjpeg_set_defaults(sp)) | |
917 | return (0); | |
918 | /* Set per-file parameters */ | |
919 | sp->photometric = td->td_photometric; | |
920 | switch (sp->photometric) { | |
921 | case PHOTOMETRIC_YCBCR: | |
922 | sp->h_sampling = td->td_ycbcrsubsampling[0]; | |
923 | sp->v_sampling = td->td_ycbcrsubsampling[1]; | |
924 | /* | |
925 | * A ReferenceBlackWhite field *must* be present since the | |
926 | * default value is inappropriate for YCbCr. Fill in the | |
927 | * proper value if application didn't set it. | |
928 | */ | |
929 | #ifdef COLORIMETRY_SUPPORT | |
930 | if (!TIFFFieldSet(tif, FIELD_REFBLACKWHITE)) { | |
931 | float refbw[6]; | |
932 | long top = 1L << td->td_bitspersample; | |
933 | refbw[0] = 0; | |
934 | refbw[1] = (float)(top-1L); | |
935 | refbw[2] = (float)(top>>1); | |
936 | refbw[3] = refbw[1]; | |
937 | refbw[4] = refbw[2]; | |
938 | refbw[5] = refbw[1]; | |
939 | TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refbw); | |
940 | } | |
941 | #endif | |
942 | break; | |
943 | case PHOTOMETRIC_PALETTE: /* disallowed by Tech Note */ | |
944 | case PHOTOMETRIC_MASK: | |
945 | TIFFError(module, | |
946 | "PhotometricInterpretation %d not allowed for JPEG", | |
947 | (int) sp->photometric); | |
948 | return (0); | |
949 | default: | |
950 | /* TIFF 6.0 forbids subsampling of all other color spaces */ | |
951 | sp->h_sampling = 1; | |
952 | sp->v_sampling = 1; | |
953 | break; | |
954 | } | |
955 | ||
956 | /* Verify miscellaneous parameters */ | |
957 | ||
958 | /* | |
959 | * This would need work if libtiff ever supports different | |
960 | * depths for different components, or if libjpeg ever supports | |
961 | * run-time selection of depth. Neither is imminent. | |
962 | */ | |
963 | if (td->td_bitspersample != BITS_IN_JSAMPLE) { | |
964 | TIFFError(module, "BitsPerSample %d not allowed for JPEG", | |
965 | (int) td->td_bitspersample); | |
966 | return (0); | |
967 | } | |
968 | sp->cinfo.c.data_precision = td->td_bitspersample; | |
969 | if (isTiled(tif)) { | |
970 | if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) { | |
971 | TIFFError(module, | |
972 | "JPEG tile height must be multiple of %d", | |
973 | sp->v_sampling * DCTSIZE); | |
974 | return (0); | |
975 | } | |
976 | if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) { | |
977 | TIFFError(module, | |
978 | "JPEG tile width must be multiple of %d", | |
979 | sp->h_sampling * DCTSIZE); | |
980 | return (0); | |
981 | } | |
982 | } else { | |
983 | if (td->td_rowsperstrip < td->td_imagelength && | |
984 | (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) { | |
985 | TIFFError(module, | |
986 | "RowsPerStrip must be multiple of %d for JPEG", | |
987 | sp->v_sampling * DCTSIZE); | |
988 | return (0); | |
989 | } | |
990 | } | |
991 | ||
992 | /* Create a JPEGTables field if appropriate */ | |
993 | if (sp->jpegtablesmode & (JPEGTABLESMODE_QUANT|JPEGTABLESMODE_HUFF)) { | |
994 | if (!prepare_JPEGTables(tif)) | |
995 | return (0); | |
996 | /* Mark the field present */ | |
997 | /* Can't use TIFFSetField since BEENWRITING is already set! */ | |
998 | TIFFSetFieldBit(tif, FIELD_JPEGTABLES); | |
999 | tif->tif_flags |= TIFF_DIRTYDIRECT; | |
1000 | } else { | |
1001 | /* We do not support application-supplied JPEGTables, */ | |
1002 | /* so mark the field not present */ | |
1003 | TIFFClrFieldBit(tif, FIELD_JPEGTABLES); | |
1004 | } | |
1005 | ||
1006 | /* Direct libjpeg output to libtiff's output buffer */ | |
1007 | TIFFjpeg_data_dest(sp, tif); | |
1008 | ||
1009 | return (1); | |
1010 | } | |
1011 | ||
1012 | /* | |
1013 | * Set encoding state at the start of a strip or tile. | |
1014 | */ | |
1015 | static int | |
1016 | JPEGPreEncode(TIFF* tif, tsample_t s) | |
1017 | { | |
1018 | JPEGState *sp = JState(tif); | |
1019 | TIFFDirectory *td = &tif->tif_dir; | |
1020 | static const char module[] = "JPEGPreEncode"; | |
1021 | uint32 segment_width, segment_height; | |
1022 | int downsampled_input; | |
1023 | ||
1024 | assert(sp != NULL); | |
1025 | assert(!sp->cinfo.comm.is_decompressor); | |
1026 | /* | |
1027 | * Set encoding parameters for this strip/tile. | |
1028 | */ | |
1029 | if (isTiled(tif)) { | |
1030 | segment_width = td->td_tilewidth; | |
1031 | segment_height = td->td_tilelength; | |
1032 | sp->bytesperline = TIFFTileRowSize(tif); | |
1033 | } else { | |
1034 | segment_width = td->td_imagewidth; | |
1035 | segment_height = td->td_imagelength - tif->tif_row; | |
1036 | if (segment_height > td->td_rowsperstrip) | |
1037 | segment_height = td->td_rowsperstrip; | |
1038 | sp->bytesperline = TIFFScanlineSize(tif); | |
1039 | } | |
1040 | if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { | |
1041 | /* for PC 2, scale down the strip/tile size | |
1042 | * to match a downsampled component | |
1043 | */ | |
1044 | segment_width = TIFFhowmany(segment_width, sp->h_sampling); | |
1045 | segment_height = TIFFhowmany(segment_height, sp->v_sampling); | |
1046 | } | |
1047 | if (segment_width > 65535 || segment_height > 65535) { | |
1048 | TIFFError(module, "Strip/tile too large for JPEG"); | |
1049 | return (0); | |
1050 | } | |
1051 | sp->cinfo.c.image_width = segment_width; | |
1052 | sp->cinfo.c.image_height = segment_height; | |
1053 | downsampled_input = FALSE; | |
1054 | if (td->td_planarconfig == PLANARCONFIG_CONTIG) { | |
1055 | sp->cinfo.c.input_components = td->td_samplesperpixel; | |
1056 | if (sp->photometric == PHOTOMETRIC_YCBCR) { | |
1057 | if (sp->jpegcolormode == JPEGCOLORMODE_RGB) { | |
1058 | sp->cinfo.c.in_color_space = JCS_RGB; | |
1059 | } else { | |
1060 | sp->cinfo.c.in_color_space = JCS_YCbCr; | |
1061 | if (sp->h_sampling != 1 || sp->v_sampling != 1) | |
1062 | downsampled_input = TRUE; | |
1063 | } | |
1064 | if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr)) | |
1065 | return (0); | |
1066 | /* | |
1067 | * Set Y sampling factors; | |
1068 | * we assume jpeg_set_colorspace() set the rest to 1 | |
1069 | */ | |
1070 | sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling; | |
1071 | sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling; | |
1072 | } else { | |
1073 | sp->cinfo.c.in_color_space = JCS_UNKNOWN; | |
1074 | if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) | |
1075 | return (0); | |
1076 | /* jpeg_set_colorspace set all sampling factors to 1 */ | |
1077 | } | |
1078 | } else { | |
1079 | sp->cinfo.c.input_components = 1; | |
1080 | sp->cinfo.c.in_color_space = JCS_UNKNOWN; | |
1081 | if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) | |
1082 | return (0); | |
1083 | sp->cinfo.c.comp_info[0].component_id = s; | |
1084 | /* jpeg_set_colorspace() set sampling factors to 1 */ | |
1085 | if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) { | |
1086 | sp->cinfo.c.comp_info[0].quant_tbl_no = 1; | |
1087 | sp->cinfo.c.comp_info[0].dc_tbl_no = 1; | |
1088 | sp->cinfo.c.comp_info[0].ac_tbl_no = 1; | |
1089 | } | |
1090 | } | |
1091 | /* ensure libjpeg won't write any extraneous markers */ | |
1092 | sp->cinfo.c.write_JFIF_header = FALSE; | |
1093 | sp->cinfo.c.write_Adobe_marker = FALSE; | |
1094 | /* set up table handling correctly */ | |
1095 | if (! (sp->jpegtablesmode & JPEGTABLESMODE_QUANT)) { | |
1096 | if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) | |
1097 | return (0); | |
1098 | unsuppress_quant_table(sp, 0); | |
1099 | unsuppress_quant_table(sp, 1); | |
1100 | } | |
1101 | if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) | |
1102 | sp->cinfo.c.optimize_coding = FALSE; | |
1103 | else | |
1104 | sp->cinfo.c.optimize_coding = TRUE; | |
1105 | if (downsampled_input) { | |
1106 | /* Need to use raw-data interface to libjpeg */ | |
1107 | sp->cinfo.c.raw_data_in = TRUE; | |
1108 | tif->tif_encoderow = JPEGEncodeRaw; | |
1109 | tif->tif_encodestrip = JPEGEncodeRaw; | |
1110 | tif->tif_encodetile = JPEGEncodeRaw; | |
1111 | } else { | |
1112 | /* Use normal interface to libjpeg */ | |
1113 | sp->cinfo.c.raw_data_in = FALSE; | |
1114 | tif->tif_encoderow = JPEGEncode; | |
1115 | tif->tif_encodestrip = JPEGEncode; | |
1116 | tif->tif_encodetile = JPEGEncode; | |
1117 | } | |
1118 | /* Start JPEG compressor */ | |
1119 | if (!TIFFjpeg_start_compress(sp, FALSE)) | |
1120 | return (0); | |
1121 | /* Allocate downsampled-data buffers if needed */ | |
1122 | if (downsampled_input) { | |
1123 | if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info, | |
1124 | sp->cinfo.c.num_components)) | |
1125 | return (0); | |
1126 | } | |
1127 | sp->scancount = 0; | |
1128 | ||
1129 | return (1); | |
1130 | } | |
1131 | ||
1132 | /* | |
1133 | * Encode a chunk of pixels. | |
1134 | * "Standard" case: incoming data is not downsampled. | |
1135 | */ | |
1136 | static int | |
1137 | JPEGEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) | |
1138 | { | |
1139 | JPEGState *sp = JState(tif); | |
1140 | tsize_t nrows; | |
1141 | JSAMPROW bufptr[1]; | |
1142 | ||
1143 | (void) s; | |
1144 | assert(sp != NULL); | |
1145 | /* data is expected to be supplied in multiples of a scanline */ | |
1146 | nrows = cc / sp->bytesperline; | |
1147 | if (cc % sp->bytesperline) | |
1148 | TIFFWarning(tif->tif_name, "fractional scanline discarded"); | |
1149 | ||
1150 | while (nrows-- > 0) { | |
1151 | bufptr[0] = (JSAMPROW) buf; | |
1152 | if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) | |
1153 | return (0); | |
1154 | if (nrows > 0) | |
1155 | tif->tif_row++; | |
1156 | buf += sp->bytesperline; | |
1157 | } | |
1158 | return (1); | |
1159 | } | |
1160 | ||
1161 | /* | |
1162 | * Encode a chunk of pixels. | |
1163 | * Incoming data is expected to be downsampled per sampling factors. | |
1164 | */ | |
1165 | static int | |
1166 | JPEGEncodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) | |
1167 | { | |
1168 | JPEGState *sp = JState(tif); | |
1169 | JSAMPLE* inptr; | |
1170 | JSAMPLE* outptr; | |
1171 | tsize_t nrows; | |
1172 | JDIMENSION clumps_per_line, nclump; | |
1173 | int clumpoffset, ci, xpos, ypos; | |
1174 | jpeg_component_info* compptr; | |
1175 | int samples_per_clump = sp->samplesperclump; | |
1176 | ||
1177 | (void) s; | |
1178 | assert(sp != NULL); | |
1179 | /* data is expected to be supplied in multiples of a scanline */ | |
1180 | nrows = cc / sp->bytesperline; | |
1181 | if (cc % sp->bytesperline) | |
1182 | TIFFWarning(tif->tif_name, "fractional scanline discarded"); | |
1183 | ||
1184 | /* Cb,Cr both have sampling factors 1, so this is correct */ | |
1185 | clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width; | |
1186 | ||
1187 | while (nrows-- > 0) { | |
1188 | /* | |
1189 | * Fastest way to separate the data is to make one pass | |
1190 | * over the scanline for each row of each component. | |
1191 | */ | |
1192 | clumpoffset = 0; /* first sample in clump */ | |
1193 | for (ci = 0, compptr = sp->cinfo.c.comp_info; | |
1194 | ci < sp->cinfo.c.num_components; | |
1195 | ci++, compptr++) { | |
1196 | int hsamp = compptr->h_samp_factor; | |
1197 | int vsamp = compptr->v_samp_factor; | |
1198 | int padding = (int) (compptr->width_in_blocks * DCTSIZE - | |
1199 | clumps_per_line * hsamp); | |
1200 | for (ypos = 0; ypos < vsamp; ypos++) { | |
1201 | inptr = ((JSAMPLE*) buf) + clumpoffset; | |
1202 | outptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos]; | |
1203 | if (hsamp == 1) { | |
1204 | /* fast path for at least Cb and Cr */ | |
1205 | for (nclump = clumps_per_line; nclump-- > 0; ) { | |
1206 | *outptr++ = inptr[0]; | |
1207 | inptr += samples_per_clump; | |
1208 | } | |
1209 | } else { | |
1210 | /* general case */ | |
1211 | for (nclump = clumps_per_line; nclump-- > 0; ) { | |
1212 | for (xpos = 0; xpos < hsamp; xpos++) | |
1213 | *outptr++ = inptr[xpos]; | |
1214 | inptr += samples_per_clump; | |
1215 | } | |
1216 | } | |
1217 | /* pad each scanline as needed */ | |
1218 | for (xpos = 0; xpos < padding; xpos++) { | |
1219 | *outptr = outptr[-1]; | |
1220 | outptr++; | |
1221 | } | |
1222 | clumpoffset += hsamp; | |
1223 | } | |
1224 | } | |
1225 | sp->scancount++; | |
1226 | if (sp->scancount >= DCTSIZE) { | |
1227 | int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; | |
1228 | if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) | |
1229 | return (0); | |
1230 | sp->scancount = 0; | |
1231 | } | |
1232 | if (nrows > 0) | |
1233 | tif->tif_row++; | |
1234 | buf += sp->bytesperline; | |
1235 | } | |
1236 | return (1); | |
1237 | } | |
1238 | ||
1239 | /* | |
1240 | * Finish up at the end of a strip or tile. | |
1241 | */ | |
1242 | static int | |
1243 | JPEGPostEncode(TIFF* tif) | |
1244 | { | |
1245 | JPEGState *sp = JState(tif); | |
1246 | ||
1247 | if (sp->scancount > 0) { | |
1248 | /* | |
1249 | * Need to emit a partial bufferload of downsampled data. | |
1250 | * Pad the data vertically. | |
1251 | */ | |
1252 | int ci, ypos, n; | |
1253 | jpeg_component_info* compptr; | |
1254 | ||
1255 | for (ci = 0, compptr = sp->cinfo.c.comp_info; | |
1256 | ci < sp->cinfo.c.num_components; | |
1257 | ci++, compptr++) { | |
1258 | int vsamp = compptr->v_samp_factor; | |
1259 | tsize_t row_width = compptr->width_in_blocks * DCTSIZE | |
1260 | * sizeof(JSAMPLE); | |
1261 | for (ypos = sp->scancount * vsamp; | |
1262 | ypos < DCTSIZE * vsamp; ypos++) { | |
1263 | _TIFFmemcpy((tdata_t)sp->ds_buffer[ci][ypos], | |
1264 | (tdata_t)sp->ds_buffer[ci][ypos-1], | |
1265 | row_width); | |
1266 | ||
1267 | } | |
1268 | } | |
1269 | n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; | |
1270 | if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) | |
1271 | return (0); | |
1272 | } | |
1273 | ||
1274 | return (TIFFjpeg_finish_compress(JState(tif))); | |
1275 | } | |
1276 | ||
1277 | static void | |
1278 | JPEGCleanup(TIFF* tif) | |
1279 | { | |
1280 | if (tif->tif_data) { | |
1281 | JPEGState *sp = JState(tif); | |
1282 | TIFFjpeg_destroy(sp); /* release libjpeg resources */ | |
1283 | if (sp->jpegtables) /* tag value */ | |
1284 | _TIFFfree(sp->jpegtables); | |
1285 | _TIFFfree(tif->tif_data); /* release local state */ | |
1286 | tif->tif_data = NULL; | |
1287 | } | |
1288 | } | |
1289 | ||
1290 | static int | |
1291 | JPEGVSetField(TIFF* tif, ttag_t tag, va_list ap) | |
1292 | { | |
1293 | JPEGState* sp = JState(tif); | |
1294 | TIFFDirectory* td = &tif->tif_dir; | |
1295 | uint32 v32; | |
1296 | ||
1297 | switch (tag) { | |
1298 | case TIFFTAG_JPEGTABLES: | |
1299 | v32 = va_arg(ap, uint32); | |
1300 | if (v32 == 0) { | |
1301 | /* XXX */ | |
1302 | return (0); | |
1303 | } | |
1304 | _TIFFsetByteArray(&sp->jpegtables, va_arg(ap, void*), | |
1305 | (long) v32); | |
1306 | sp->jpegtables_length = v32; | |
1307 | TIFFSetFieldBit(tif, FIELD_JPEGTABLES); | |
1308 | break; | |
1309 | case TIFFTAG_JPEGQUALITY: | |
1310 | sp->jpegquality = va_arg(ap, int); | |
1311 | return (1); /* pseudo tag */ | |
1312 | case TIFFTAG_JPEGCOLORMODE: | |
1313 | sp->jpegcolormode = va_arg(ap, int); | |
1314 | /* | |
1315 | * Mark whether returned data is up-sampled or not | |
1316 | * so TIFFStripSize and TIFFTileSize return values | |
1317 | * that reflect the true amount of data. | |
1318 | */ | |
1319 | tif->tif_flags &= ~TIFF_UPSAMPLED; | |
1320 | if (td->td_planarconfig == PLANARCONFIG_CONTIG) { | |
1321 | if (td->td_photometric == PHOTOMETRIC_YCBCR && | |
1322 | sp->jpegcolormode == JPEGCOLORMODE_RGB) { | |
1323 | tif->tif_flags |= TIFF_UPSAMPLED; | |
1324 | } else { | |
1325 | if (td->td_ycbcrsubsampling[0] != 1 || | |
1326 | td->td_ycbcrsubsampling[1] != 1) | |
1327 | ; /* XXX what about up-sampling? */ | |
1328 | } | |
1329 | } | |
1330 | /* | |
1331 | * Must recalculate cached tile size | |
1332 | * in case sampling state changed. | |
1333 | */ | |
1334 | tif->tif_tilesize = TIFFTileSize(tif); | |
1335 | return (1); /* pseudo tag */ | |
1336 | case TIFFTAG_JPEGTABLESMODE: | |
1337 | sp->jpegtablesmode = va_arg(ap, int); | |
1338 | return (1); /* pseudo tag */ | |
1339 | default: | |
1340 | return (*sp->vsetparent)(tif, tag, ap); | |
1341 | } | |
1342 | tif->tif_flags |= TIFF_DIRTYDIRECT; | |
1343 | return (1); | |
1344 | } | |
1345 | ||
1346 | static int | |
1347 | JPEGVGetField(TIFF* tif, ttag_t tag, va_list ap) | |
1348 | { | |
1349 | JPEGState* sp = JState(tif); | |
1350 | ||
1351 | switch (tag) { | |
1352 | case TIFFTAG_JPEGTABLES: | |
1353 | /* u_short is bogus --- should be uint32 ??? */ | |
1354 | /* TIFFWriteNormalTag needs fixed XXX */ | |
1355 | *va_arg(ap, u_short*) = (u_short) sp->jpegtables_length; | |
1356 | *va_arg(ap, void**) = sp->jpegtables; | |
1357 | break; | |
1358 | case TIFFTAG_JPEGQUALITY: | |
1359 | *va_arg(ap, int*) = sp->jpegquality; | |
1360 | break; | |
1361 | case TIFFTAG_JPEGCOLORMODE: | |
1362 | *va_arg(ap, int*) = sp->jpegcolormode; | |
1363 | break; | |
1364 | case TIFFTAG_JPEGTABLESMODE: | |
1365 | *va_arg(ap, int*) = sp->jpegtablesmode; | |
1366 | break; | |
1367 | default: | |
1368 | return (*sp->vgetparent)(tif, tag, ap); | |
1369 | } | |
1370 | return (1); | |
1371 | } | |
1372 | ||
1373 | static void | |
1374 | JPEGPrintDir(TIFF* tif, FILE* fd, long flags) | |
1375 | { | |
1376 | JPEGState* sp = JState(tif); | |
1377 | ||
1378 | (void) flags; | |
1379 | if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) | |
1380 | fprintf(fd, " JPEG Tables: (%lu bytes)\n", | |
1381 | (u_long) sp->jpegtables_length); | |
1382 | } | |
1383 | ||
1384 | static uint32 | |
1385 | JPEGDefaultStripSize(TIFF* tif, uint32 s) | |
1386 | { | |
1387 | JPEGState* sp = JState(tif); | |
1388 | TIFFDirectory *td = &tif->tif_dir; | |
1389 | ||
1390 | s = (*sp->defsparent)(tif, s); | |
1391 | if (s < td->td_imagelength) | |
1392 | s = TIFFroundup(s, td->td_ycbcrsubsampling[1] * DCTSIZE); | |
1393 | return (s); | |
1394 | } | |
1395 | ||
1396 | static void | |
1397 | JPEGDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) | |
1398 | { | |
1399 | JPEGState* sp = JState(tif); | |
1400 | TIFFDirectory *td = &tif->tif_dir; | |
1401 | ||
1402 | (*sp->deftparent)(tif, tw, th); | |
1403 | *tw = TIFFroundup(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE); | |
1404 | *th = TIFFroundup(*th, td->td_ycbcrsubsampling[1] * DCTSIZE); | |
1405 | } | |
1406 | ||
1407 | int | |
1408 | TIFFInitJPEG(TIFF* tif, int scheme) | |
1409 | { | |
1410 | JPEGState* sp; | |
1411 | ||
1412 | assert(scheme == COMPRESSION_JPEG); | |
1413 | ||
1414 | /* | |
1415 | * Allocate state block so tag methods have storage to record values. | |
1416 | */ | |
1417 | tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (JPEGState)); | |
1418 | if (tif->tif_data == NULL) { | |
1419 | TIFFError("TIFFInitJPEG", "No space for JPEG state block"); | |
1420 | return (0); | |
1421 | } | |
1422 | sp = JState(tif); | |
1423 | sp->tif = tif; /* back link */ | |
1424 | ||
1425 | /* | |
1426 | * Merge codec-specific tag information and | |
1427 | * override parent get/set field methods. | |
1428 | */ | |
1429 | _TIFFMergeFieldInfo(tif, jpegFieldInfo, N(jpegFieldInfo)); | |
1430 | sp->vgetparent = tif->tif_vgetfield; | |
1431 | tif->tif_vgetfield = JPEGVGetField; /* hook for codec tags */ | |
1432 | sp->vsetparent = tif->tif_vsetfield; | |
1433 | tif->tif_vsetfield = JPEGVSetField; /* hook for codec tags */ | |
1434 | tif->tif_printdir = JPEGPrintDir; /* hook for codec tags */ | |
1435 | ||
1436 | /* Default values for codec-specific fields */ | |
1437 | sp->jpegtables = NULL; | |
1438 | sp->jpegtables_length = 0; | |
1439 | sp->jpegquality = 75; /* Default IJG quality */ | |
1440 | sp->jpegcolormode = JPEGCOLORMODE_RAW; | |
1441 | sp->jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF; | |
1442 | ||
1443 | /* | |
1444 | * Install codec methods. | |
1445 | */ | |
1446 | tif->tif_setupdecode = JPEGSetupDecode; | |
1447 | tif->tif_predecode = JPEGPreDecode; | |
1448 | tif->tif_decoderow = JPEGDecode; | |
1449 | tif->tif_decodestrip = JPEGDecode; | |
1450 | tif->tif_decodetile = JPEGDecode; | |
1451 | tif->tif_setupencode = JPEGSetupEncode; | |
1452 | tif->tif_preencode = JPEGPreEncode; | |
1453 | tif->tif_postencode = JPEGPostEncode; | |
1454 | tif->tif_encoderow = JPEGEncode; | |
1455 | tif->tif_encodestrip = JPEGEncode; | |
1456 | tif->tif_encodetile = JPEGEncode; | |
1457 | tif->tif_cleanup = JPEGCleanup; | |
1458 | sp->defsparent = tif->tif_defstripsize; | |
1459 | tif->tif_defstripsize = JPEGDefaultStripSize; | |
1460 | sp->deftparent = tif->tif_deftilesize; | |
1461 | tif->tif_deftilesize = JPEGDefaultTileSize; | |
1462 | tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */ | |
1463 | ||
1464 | /* | |
1465 | * Initialize libjpeg. | |
1466 | */ | |
1467 | if (tif->tif_mode == O_RDONLY) { | |
1468 | if (!TIFFjpeg_create_decompress(sp)) | |
1469 | return (0); | |
1470 | } else { | |
1471 | if (!TIFFjpeg_create_compress(sp)) | |
1472 | return (0); | |
1473 | } | |
1474 | ||
1475 | return (1); | |
1476 | } | |
1477 | #endif /* JPEG_SUPPORT */ |