ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tif_ojpeg.c
Go to the documentation of this file.
00001 /* $Id: tif_ojpeg.c,v 1.24.2.6 2010-06-08 23:29:51 bfriesen Exp $ */
00002 
00003 /* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0
00004    specification is now totally obsolete and deprecated for new applications and
00005    images. This file was was created solely in order to read unconverted images
00006    still present on some users' computer systems. It will never be extended
00007    to write such files. Writing new-style JPEG compressed TIFFs is implemented
00008    in tif_jpeg.c.
00009 
00010    The code is carefully crafted to robustly read all gathered JPEG-in-TIFF
00011    testfiles, and anticipate as much as possible all other... But still, it may
00012    fail on some. If you encounter problems, please report them on the TIFF
00013    mailing list and/or to Joris Van Damme <info@awaresystems.be>.
00014 
00015    Please read the file called "TIFF Technical Note #2" if you need to be
00016    convinced this compression scheme is bad and breaks TIFF. That document
00017    is linked to from the LibTiff site <http://www.remotesensing.org/libtiff/>
00018    and from AWare Systems' TIFF section
00019    <http://www.awaresystems.be/imaging/tiff.html>. It is also absorbed
00020    in Adobe's specification supplements, marked "draft" up to this day, but
00021    supported by the TIFF community.
00022 
00023    This file interfaces with Release 6B of the JPEG Library written by the
00024    Independent JPEG Group. Previous versions of this file required a hack inside
00025    the LibJpeg library. This version no longer requires that. Remember to
00026    remove the hack if you update from the old version.
00027 
00028    Copyright (c) Joris Van Damme <info@awaresystems.be>
00029    Copyright (c) AWare Systems <http://www.awaresystems.be/>
00030 
00031    The licence agreement for this file is the same as the rest of the LibTiff
00032    library.
00033 
00034    IN NO EVENT SHALL JORIS VAN DAMME OR AWARE SYSTEMS BE LIABLE FOR
00035    ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
00036    OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00037    WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
00038    LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
00039    OF THIS SOFTWARE.
00040 
00041    Joris Van Damme and/or AWare Systems may be available for custom
00042    developement. If you like what you see, and need anything similar or related,
00043    contact <info@awaresystems.be>.
00044 */
00045 
00046 /* What is what, and what is not?
00047 
00048    This decoder starts with an input stream, that is essentially the JpegInterchangeFormat
00049    stream, if any, followed by the strile data, if any. This stream is read in
00050    OJPEGReadByte and related functions.
00051 
00052    It analyzes the start of this stream, until it encounters non-marker data, i.e.
00053    compressed image data. Some of the header markers it sees have no actual content,
00054    like the SOI marker, and APP/COM markers that really shouldn't even be there. Some
00055    other markers do have content, and the valuable bits and pieces of information
00056    in these markers are saved, checking all to verify that the stream is more or
00057    less within expected bounds. This happens inside the OJPEGReadHeaderInfoSecStreamXxx
00058    functions.
00059 
00060    Some OJPEG imagery contains no valid JPEG header markers. This situation is picked
00061    up on if we've seen no SOF marker when we're at the start of the compressed image
00062    data. In this case, the tables are read from JpegXxxTables tags, and the other
00063    bits and pieces of information is initialized to its most basic value. This is
00064    implemented in the OJPEGReadHeaderInfoSecTablesXxx functions.
00065 
00066    When this is complete, a good and valid JPEG header can be assembled, and this is
00067    passed through to LibJpeg. When that's done, the remainder of the input stream, i.e.
00068    the compressed image data, can be passed through unchanged. This is done in
00069    OJPEGWriteStream functions.
00070 
00071    LibTiff rightly expects to know the subsampling values before decompression. Just like
00072    in new-style JPEG-in-TIFF, though, or even more so, actually, the YCbCrsubsampling
00073    tag is notoriously unreliable. To correct these tag values with the ones inside
00074    the JPEG stream, the first part of the input stream is pre-scanned in
00075    OJPEGSubsamplingCorrect, making no note of any other data, reporting no warnings
00076    or errors, up to the point where either these values are read, or it's clear they
00077    aren't there. This means that some of the data is read twice, but we feel speed
00078    in correcting these values is important enough to warrant this sacrifice. Allthough
00079    there is currently no define or other configuration mechanism to disable this behaviour,
00080    the actual header scanning is build to robustly respond with error report if it
00081    should encounter an uncorrected mismatch of subsampling values. See
00082    OJPEGReadHeaderInfoSecStreamSof.
00083 
00084    The restart interval and restart markers are the most tricky part... The restart
00085    interval can be specified in a tag. It can also be set inside the input JPEG stream.
00086    It can be used inside the input JPEG stream. If reading from strile data, we've
00087    consistenly discovered the need to insert restart markers in between the different
00088    striles, as is also probably the most likely interpretation of the original TIFF 6.0
00089    specification. With all this setting of interval, and actual use of markers that is not
00090    predictable at the time of valid JPEG header assembly, the restart thing may turn
00091    out the Achilles heel of this implementation. Fortunately, most OJPEG writer vendors
00092    succeed in reading back what they write, which may be the reason why we've been able
00093    to discover ways that seem to work.
00094 
00095    Some special provision is made for planarconfig separate OJPEG files. These seem
00096    to consistently contain header info, a SOS marker, a plane, SOS marker, plane, SOS,
00097    and plane. This may or may not be a valid JPEG configuration, we don't know and don't
00098    care. We want LibTiff to be able to access the planes individually, without huge
00099    buffering inside LibJpeg, anyway. So we compose headers to feed to LibJpeg, in this
00100    case, that allow us to pass a single plane such that LibJpeg sees a valid
00101    single-channel JPEG stream. Locating subsequent SOS markers, and thus subsequent
00102    planes, is done inside OJPEGReadSecondarySos.
00103 
00104    The benefit of the scheme is... that it works, basically. We know of no other that
00105    does. It works without checking software tag, or otherwise going about things in an
00106    OJPEG flavor specific manner. Instead, it is a single scheme, that covers the cases
00107    with and without JpegInterchangeFormat, with and without striles, with part of
00108    the header in JpegInterchangeFormat and remainder in first strile, etc. It is forgiving
00109    and robust, may likely work with OJPEG flavors we've not seen yet, and makes most out
00110    of the data.
00111 
00112    Another nice side-effect is that a complete JPEG single valid stream is build if
00113    planarconfig is not separate (vast majority). We may one day use that to build
00114    converters to JPEG, and/or to new-style JPEG compression inside TIFF.
00115 
00116    A dissadvantage is the lack of random access to the individual striles. This is the
00117    reason for much of the complicated restart-and-position stuff inside OJPEGPreDecode.
00118    Applications would do well accessing all striles in order, as this will result in
00119    a single sequential scan of the input stream, and no restarting of LibJpeg decoding
00120    session.
00121 */
00122 
00123 
00124 #include "tiffiop.h"
00125 #ifdef OJPEG_SUPPORT
00126 
00127 /* Configuration defines here are:
00128  * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some environments,
00129  *  like eg LibTiffDelphi, this is not possible. For this reason, the actual calls to
00130  *  libjpeg, with longjump stuff, are encapsulated in dedicated functions. When
00131  *  JPEG_ENCAP_EXTERNAL is defined, these encapsulating functions are declared external
00132  *  to this unit, and can be defined elsewhere to use stuff other then longjump.
00133  *  The default mode, without JPEG_ENCAP_EXTERNAL, implements the call encapsulators
00134  *  here, internally, with normal longjump.
00135  * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent is
00136  *  conviniently available, but still it may be worthwhile to use _setjmp or sigsetjmp
00137  *  in place of plain setjmp. These macros will make it easier. It is useless
00138  *  to fiddle with these if you define JPEG_ENCAP_EXTERNAL.
00139  * OJPEG_BUFFER: Define the size of the desired buffer here. Should be small enough so as to guarantee
00140  *  instant processing, optimal streaming and optimal use of processor cache, but also big
00141  *  enough so as to not result in significant call overhead. It should be at least a few
00142  *  bytes to accomodate some structures (this is verified in asserts), but it would not be
00143  *  sensible to make it this small anyway, and it should be at most 64K since it is indexed
00144  *  with uint16. We recommend 2K.
00145  * EGYPTIANWALK: You could also define EGYPTIANWALK here, but it is not used anywhere and has
00146  *  absolutely no effect. That is why most people insist the EGYPTIANWALK is a bit silly.
00147  */
00148 
00149 /* #define LIBJPEG_ENCAP_EXTERNAL */
00150 #define SETJMP(jbuf) setjmp(jbuf)
00151 #define LONGJMP(jbuf,code) longjmp(jbuf,code)
00152 #define JMP_BUF jmp_buf
00153 #define OJPEG_BUFFER 2048
00154 /* define EGYPTIANWALK */
00155 
00156 #define JPEG_MARKER_SOF0 0xC0
00157 #define JPEG_MARKER_SOF1 0xC1
00158 #define JPEG_MARKER_SOF3 0xC3
00159 #define JPEG_MARKER_DHT 0xC4
00160 #define JPEG_MARKER_RST0 0XD0
00161 #define JPEG_MARKER_SOI 0xD8
00162 #define JPEG_MARKER_EOI 0xD9
00163 #define JPEG_MARKER_SOS 0xDA
00164 #define JPEG_MARKER_DQT 0xDB
00165 #define JPEG_MARKER_DRI 0xDD
00166 #define JPEG_MARKER_APP0 0xE0
00167 #define JPEG_MARKER_COM 0xFE
00168 
00169 #define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC+0)
00170 #define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC+1)
00171 #define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC+2)
00172 #define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC+3)
00173 #define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC+4)
00174 #define FIELD_OJPEG_JPEGPROC (FIELD_CODEC+5)
00175 #define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC+6)
00176 #define FIELD_OJPEG_COUNT 7
00177 
00178 static const TIFFFieldInfo ojpeg_field_info[] = {
00179     {TIFFTAG_JPEGIFOFFSET,1,1,TIFF_LONG,FIELD_OJPEG_JPEGINTERCHANGEFORMAT,TRUE,FALSE,"JpegInterchangeFormat"},
00180     {TIFFTAG_JPEGIFBYTECOUNT,1,1,TIFF_LONG,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH,TRUE,FALSE,"JpegInterchangeFormatLength"},
00181     {TIFFTAG_JPEGQTABLES,TIFF_VARIABLE,TIFF_VARIABLE,TIFF_LONG,FIELD_OJPEG_JPEGQTABLES,FALSE,TRUE,"JpegQTables"},
00182     {TIFFTAG_JPEGDCTABLES,TIFF_VARIABLE,TIFF_VARIABLE,TIFF_LONG,FIELD_OJPEG_JPEGDCTABLES,FALSE,TRUE,"JpegDcTables"},
00183     {TIFFTAG_JPEGACTABLES,TIFF_VARIABLE,TIFF_VARIABLE,TIFF_LONG,FIELD_OJPEG_JPEGACTABLES,FALSE,TRUE,"JpegAcTables"},
00184     {TIFFTAG_JPEGPROC,1,1,TIFF_SHORT,FIELD_OJPEG_JPEGPROC,FALSE,FALSE,"JpegProc"},
00185     {TIFFTAG_JPEGRESTARTINTERVAL,1,1,TIFF_SHORT,FIELD_OJPEG_JPEGRESTARTINTERVAL,FALSE,FALSE,"JpegRestartInterval"},
00186 };
00187 
00188 #ifndef LIBJPEG_ENCAP_EXTERNAL
00189 #include <setjmp.h>
00190 #endif
00191 
00192 #include "jpeglib.h"
00193 #include "jerror.h"
00194 
00195 typedef struct jpeg_error_mgr jpeg_error_mgr;
00196 typedef struct jpeg_common_struct jpeg_common_struct;
00197 typedef struct jpeg_decompress_struct jpeg_decompress_struct;
00198 typedef struct jpeg_source_mgr jpeg_source_mgr;
00199 
00200 typedef enum {
00201     osibsNotSetYet,
00202     osibsJpegInterchangeFormat,
00203     osibsStrile,
00204     osibsEof
00205 } OJPEGStateInBufferSource;
00206 
00207 typedef enum {
00208     ososSoi,
00209     ososQTable0,ososQTable1,ososQTable2,ososQTable3,
00210     ososDcTable0,ososDcTable1,ososDcTable2,ososDcTable3,
00211     ososAcTable0,ososAcTable1,ososAcTable2,ososAcTable3,
00212     ososDri,
00213     ososSof,
00214     ososSos,
00215     ososCompressed,
00216     ososRst,
00217     ososEoi
00218 } OJPEGStateOutState;
00219 
00220 typedef struct {
00221     TIFF* tif;
00222     #ifndef LIBJPEG_ENCAP_EXTERNAL
00223     JMP_BUF exit_jmpbuf;
00224     #endif
00225     TIFFVGetMethod vgetparent;
00226     TIFFVSetMethod vsetparent;
00227     toff_t file_size;
00228     uint32 image_width;
00229     uint32 image_length;
00230     uint32 strile_width;
00231     uint32 strile_length;
00232     uint32 strile_length_total;
00233     uint8 samples_per_pixel;
00234     uint8 plane_sample_offset;
00235     uint8 samples_per_pixel_per_plane;
00236     toff_t jpeg_interchange_format;
00237     toff_t jpeg_interchange_format_length;
00238     uint8 jpeg_proc;
00239     uint8 subsamplingcorrect;
00240     uint8 subsamplingcorrect_done;
00241     uint8 subsampling_tag;
00242     uint8 subsampling_hor;
00243     uint8 subsampling_ver;
00244     uint8 subsampling_force_desubsampling_inside_decompression;
00245     uint8 qtable_offset_count;
00246     uint8 dctable_offset_count;
00247     uint8 actable_offset_count;
00248     toff_t qtable_offset[3];
00249     toff_t dctable_offset[3];
00250     toff_t actable_offset[3];
00251     uint8* qtable[4];
00252     uint8* dctable[4];
00253     uint8* actable[4];
00254     uint16 restart_interval;
00255     uint8 restart_index;
00256     uint8 sof_log;
00257     uint8 sof_marker_id;
00258     uint32 sof_x;
00259     uint32 sof_y;
00260     uint8 sof_c[3];
00261     uint8 sof_hv[3];
00262     uint8 sof_tq[3];
00263     uint8 sos_cs[3];
00264     uint8 sos_tda[3];
00265     struct {
00266         uint8 log;
00267         OJPEGStateInBufferSource in_buffer_source;
00268         tstrile_t in_buffer_next_strile;
00269         toff_t in_buffer_file_pos;
00270         toff_t in_buffer_file_togo;
00271     } sos_end[3];
00272     uint8 readheader_done;
00273     uint8 writeheader_done;
00274     tsample_t write_cursample;
00275     tstrile_t write_curstrile;
00276     uint8 libjpeg_session_active;
00277     uint8 libjpeg_jpeg_query_style;
00278     jpeg_error_mgr libjpeg_jpeg_error_mgr;
00279     jpeg_decompress_struct libjpeg_jpeg_decompress_struct;
00280     jpeg_source_mgr libjpeg_jpeg_source_mgr;
00281     uint8 subsampling_convert_log;
00282     uint32 subsampling_convert_ylinelen;
00283     uint32 subsampling_convert_ylines;
00284     uint32 subsampling_convert_clinelen;
00285     uint32 subsampling_convert_clines;
00286     uint32 subsampling_convert_ybuflen;
00287     uint32 subsampling_convert_cbuflen;
00288     uint32 subsampling_convert_ycbcrbuflen;
00289     uint8* subsampling_convert_ycbcrbuf;
00290     uint8* subsampling_convert_ybuf;
00291     uint8* subsampling_convert_cbbuf;
00292     uint8* subsampling_convert_crbuf;
00293     uint32 subsampling_convert_ycbcrimagelen;
00294     uint8** subsampling_convert_ycbcrimage;
00295     uint32 subsampling_convert_clinelenout;
00296     uint32 subsampling_convert_state;
00297     uint32 bytes_per_line;   /* if the codec outputs subsampled data, a 'line' in bytes_per_line */
00298     uint32 lines_per_strile; /* and lines_per_strile means subsampling_ver desubsampled rows     */
00299     OJPEGStateInBufferSource in_buffer_source;
00300     tstrile_t in_buffer_next_strile;
00301     tstrile_t in_buffer_strile_count;
00302     toff_t in_buffer_file_pos;
00303     uint8 in_buffer_file_pos_log;
00304     toff_t in_buffer_file_togo;
00305     uint16 in_buffer_togo;
00306     uint8* in_buffer_cur;
00307     uint8 in_buffer[OJPEG_BUFFER];
00308     OJPEGStateOutState out_state;
00309     uint8 out_buffer[OJPEG_BUFFER];
00310     uint8* skip_buffer;
00311 } OJPEGState;
00312 
00313 static int OJPEGVGetField(TIFF* tif, ttag_t tag, va_list ap);
00314 static int OJPEGVSetField(TIFF* tif, ttag_t tag, va_list ap);
00315 static void OJPEGPrintDir(TIFF* tif, FILE* fd, long flags);
00316 
00317 static int OJPEGSetupDecode(TIFF* tif);
00318 static int OJPEGPreDecode(TIFF* tif, tsample_t s);
00319 static int OJPEGPreDecodeSkipRaw(TIFF* tif);
00320 static int OJPEGPreDecodeSkipScanlines(TIFF* tif);
00321 static int OJPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s);
00322 static int OJPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc);
00323 static int OJPEGDecodeScanlines(TIFF* tif, tidata_t buf, tsize_t cc);
00324 static void OJPEGPostDecode(TIFF* tif, tidata_t buf, tsize_t cc);
00325 static int OJPEGSetupEncode(TIFF* tif);
00326 static int OJPEGPreEncode(TIFF* tif, tsample_t s);
00327 static int OJPEGEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s);
00328 static int OJPEGPostEncode(TIFF* tif);
00329 static void OJPEGCleanup(TIFF* tif);
00330 
00331 static void OJPEGSubsamplingCorrect(TIFF* tif);
00332 static int OJPEGReadHeaderInfo(TIFF* tif);
00333 static int OJPEGReadSecondarySos(TIFF* tif, tsample_t s);
00334 static int OJPEGWriteHeaderInfo(TIFF* tif);
00335 static void OJPEGLibjpegSessionAbort(TIFF* tif);
00336 
00337 static int OJPEGReadHeaderInfoSec(TIFF* tif);
00338 static int OJPEGReadHeaderInfoSecStreamDri(TIFF* tif);
00339 static int OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif);
00340 static int OJPEGReadHeaderInfoSecStreamDht(TIFF* tif);
00341 static int OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id);
00342 static int OJPEGReadHeaderInfoSecStreamSos(TIFF* tif);
00343 static int OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif);
00344 static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif);
00345 static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif);
00346 
00347 static int OJPEGReadBufferFill(OJPEGState* sp);
00348 static int OJPEGReadByte(OJPEGState* sp, uint8* byte);
00349 static int OJPEGReadBytePeek(OJPEGState* sp, uint8* byte);
00350 static void OJPEGReadByteAdvance(OJPEGState* sp);
00351 static int OJPEGReadWord(OJPEGState* sp, uint16* word);
00352 static int OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem);
00353 static void OJPEGReadSkip(OJPEGState* sp, uint16 len);
00354 
00355 static int OJPEGWriteStream(TIFF* tif, void** mem, uint32* len);
00356 static void OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len);
00357 static void OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
00358 static void OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
00359 static void OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
00360 static void OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len);
00361 static void OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len);
00362 static void OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len);
00363 static int OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len);
00364 static void OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len);
00365 static void OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len);
00366 
00367 #ifdef LIBJPEG_ENCAP_EXTERNAL
00368 extern int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
00369 extern int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image);
00370 extern int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
00371 extern int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines);
00372 extern int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines);
00373 extern void jpeg_encap_unwind(TIFF* tif);
00374 #else
00375 static int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* j);
00376 static int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image);
00377 static int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
00378 static int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines);
00379 static int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines);
00380 static void jpeg_encap_unwind(TIFF* tif);
00381 #endif
00382 
00383 static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo);
00384 static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo);
00385 static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo);
00386 static boolean OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo);
00387 static void OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes);
00388 static boolean OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired);
00389 static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo);
00390 
00391 int
00392 TIFFInitOJPEG(TIFF* tif, int scheme)
00393 {
00394     static const char module[]="TIFFInitOJPEG";
00395     OJPEGState* sp;
00396 
00397     assert(scheme==COMPRESSION_OJPEG);
00398 
00399         /*
00400      * Merge codec-specific tag information.
00401      */
00402     if (!_TIFFMergeFieldInfo(tif,ojpeg_field_info,FIELD_OJPEG_COUNT)) {
00403         TIFFErrorExt(tif->tif_clientdata, module,
00404                  "Merging Old JPEG codec-specific tags failed");
00405         return 0;
00406     }
00407 
00408     /* state block */
00409     sp=_TIFFmalloc(sizeof(OJPEGState));
00410     if (sp==NULL)
00411     {
00412         TIFFErrorExt(tif->tif_clientdata,module,"No space for OJPEG state block");
00413         return(0);
00414     }
00415     _TIFFmemset(sp,0,sizeof(OJPEGState));
00416     sp->tif=tif;
00417     sp->jpeg_proc=1;
00418     sp->subsampling_hor=2;
00419     sp->subsampling_ver=2;
00420     TIFFSetField(tif,TIFFTAG_YCBCRSUBSAMPLING,2,2);
00421     /* tif codec methods */
00422     tif->tif_setupdecode=OJPEGSetupDecode;
00423     tif->tif_predecode=OJPEGPreDecode;
00424     tif->tif_postdecode=OJPEGPostDecode;
00425     tif->tif_decoderow=OJPEGDecode;
00426     tif->tif_decodestrip=OJPEGDecode;
00427     tif->tif_decodetile=OJPEGDecode;
00428     tif->tif_setupencode=OJPEGSetupEncode;
00429     tif->tif_preencode=OJPEGPreEncode;
00430     tif->tif_postencode=OJPEGPostEncode;
00431     tif->tif_encoderow=OJPEGEncode;
00432     tif->tif_encodestrip=OJPEGEncode;
00433     tif->tif_encodetile=OJPEGEncode;
00434     tif->tif_cleanup=OJPEGCleanup;
00435     tif->tif_data=(tidata_t)sp;
00436     /* tif tag methods */
00437     sp->vgetparent=tif->tif_tagmethods.vgetfield;
00438     tif->tif_tagmethods.vgetfield=OJPEGVGetField;
00439     sp->vsetparent=tif->tif_tagmethods.vsetfield;
00440     tif->tif_tagmethods.vsetfield=OJPEGVSetField;
00441     tif->tif_tagmethods.printdir=OJPEGPrintDir;
00442     /* Some OJPEG files don't have strip or tile offsets or bytecounts tags.
00443        Some others do, but have totally meaningless or corrupt values
00444        in these tags. In these cases, the JpegInterchangeFormat stream is
00445        reliable. In any case, this decoder reads the compressed data itself,
00446        from the most reliable locations, and we need to notify encapsulating
00447        LibTiff not to read raw strips or tiles for us. */
00448     tif->tif_flags|=TIFF_NOREADRAW;
00449     return(1);
00450 }
00451 
00452 static int
00453 OJPEGVGetField(TIFF* tif, ttag_t tag, va_list ap)
00454 {
00455     OJPEGState* sp=(OJPEGState*)tif->tif_data;
00456     switch(tag)
00457     {
00458         case TIFFTAG_JPEGIFOFFSET:
00459             *va_arg(ap,uint32*)=(uint32)sp->jpeg_interchange_format;
00460             break;
00461         case TIFFTAG_JPEGIFBYTECOUNT:
00462             *va_arg(ap,uint32*)=(uint32)sp->jpeg_interchange_format_length;
00463             break;
00464         case TIFFTAG_YCBCRSUBSAMPLING:
00465             if (sp->subsamplingcorrect_done==0)
00466                 OJPEGSubsamplingCorrect(tif);
00467             *va_arg(ap,uint16*)=(uint16)sp->subsampling_hor;
00468             *va_arg(ap,uint16*)=(uint16)sp->subsampling_ver;
00469             break;
00470         case TIFFTAG_JPEGQTABLES:
00471             *va_arg(ap,uint32*)=(uint32)sp->qtable_offset_count;
00472             *va_arg(ap,void**)=(void*)sp->qtable_offset;
00473             break;
00474         case TIFFTAG_JPEGDCTABLES:
00475             *va_arg(ap,uint32*)=(uint32)sp->dctable_offset_count;
00476             *va_arg(ap,void**)=(void*)sp->dctable_offset;
00477             break;
00478         case TIFFTAG_JPEGACTABLES:
00479             *va_arg(ap,uint32*)=(uint32)sp->actable_offset_count;
00480             *va_arg(ap,void**)=(void*)sp->actable_offset;
00481             break;
00482         case TIFFTAG_JPEGPROC:
00483             *va_arg(ap,uint16*)=(uint16)sp->jpeg_proc;
00484             break;
00485         case TIFFTAG_JPEGRESTARTINTERVAL:
00486             *va_arg(ap,uint16*)=sp->restart_interval;
00487             break;
00488         default:
00489             return (*sp->vgetparent)(tif,tag,ap);
00490     }
00491     return (1);
00492 }
00493 
00494 static int
00495 OJPEGVSetField(TIFF* tif, ttag_t tag, va_list ap)
00496 {
00497     static const char module[]="OJPEGVSetField";
00498     OJPEGState* sp=(OJPEGState*)tif->tif_data;
00499     uint32 ma;
00500     uint32* mb;
00501     uint32 n;
00502     switch(tag)
00503     {
00504         case TIFFTAG_JPEGIFOFFSET:
00505             sp->jpeg_interchange_format=(toff_t)va_arg(ap,uint32);  
00506             break;
00507         case TIFFTAG_JPEGIFBYTECOUNT:
00508             sp->jpeg_interchange_format_length=(toff_t)va_arg(ap,uint32);  
00509             break;
00510         case TIFFTAG_YCBCRSUBSAMPLING:
00511             sp->subsampling_tag=1;
00512             sp->subsampling_hor=(uint8)va_arg(ap,int);
00513             sp->subsampling_ver=(uint8)va_arg(ap,int);
00514             tif->tif_dir.td_ycbcrsubsampling[0]=sp->subsampling_hor;
00515             tif->tif_dir.td_ycbcrsubsampling[1]=sp->subsampling_ver;
00516             break;
00517         case TIFFTAG_JPEGQTABLES:
00518             ma=va_arg(ap,uint32);
00519             if (ma!=0)
00520             {
00521                 if (ma>3)
00522                 {
00523                     TIFFErrorExt(tif->tif_clientdata,module,"JpegQTables tag has incorrect count");
00524                     return(0);
00525                 }
00526                 sp->qtable_offset_count=(uint8)ma;
00527                 mb=va_arg(ap,uint32*);
00528                 for (n=0; n<ma; n++)
00529                     sp->qtable_offset[n]=(toff_t)mb[n];
00530             }
00531             break;
00532         case TIFFTAG_JPEGDCTABLES:
00533             ma=va_arg(ap,uint32);
00534             if (ma!=0)
00535             {
00536                 if (ma>3)
00537                 {
00538                     TIFFErrorExt(tif->tif_clientdata,module,"JpegDcTables tag has incorrect count");
00539                     return(0);
00540                 }
00541                 sp->dctable_offset_count=(uint8)ma;
00542                 mb=va_arg(ap,uint32*);
00543                 for (n=0; n<ma; n++)
00544                     sp->dctable_offset[n]=(toff_t)mb[n];
00545             }
00546             break;
00547         case TIFFTAG_JPEGACTABLES:
00548             ma=va_arg(ap,uint32);
00549             if (ma!=0)
00550             {
00551                 if (ma>3)
00552                 {
00553                     TIFFErrorExt(tif->tif_clientdata,module,"JpegAcTables tag has incorrect count");
00554                     return(0);
00555                 }
00556                 sp->actable_offset_count=(uint8)ma;
00557                 mb=va_arg(ap,uint32*);
00558                 for (n=0; n<ma; n++)
00559                     sp->actable_offset[n]=(toff_t)mb[n];
00560             }
00561             break;
00562         case TIFFTAG_JPEGPROC:
00563             sp->jpeg_proc=(uint8)va_arg(ap,uint32);
00564             break;
00565         case TIFFTAG_JPEGRESTARTINTERVAL:
00566             sp->restart_interval=(uint16)va_arg(ap,uint32);
00567             break;
00568         default:
00569             return (*sp->vsetparent)(tif,tag,ap);
00570     }
00571     TIFFSetFieldBit(tif,_TIFFFieldWithTag(tif,tag)->field_bit);
00572     tif->tif_flags|=TIFF_DIRTYDIRECT;
00573     return(1);
00574 }
00575 
00576 static void
00577 OJPEGPrintDir(TIFF* tif, FILE* fd, long flags)
00578 {
00579     OJPEGState* sp=(OJPEGState*)tif->tif_data;
00580     uint8 m;
00581     (void)flags;
00582     assert(sp!=NULL);
00583     if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMAT))
00584         fprintf(fd,"  JpegInterchangeFormat: %lu\n",(unsigned long)sp->jpeg_interchange_format);
00585     if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH))
00586         fprintf(fd,"  JpegInterchangeFormatLength: %lu\n",(unsigned long)sp->jpeg_interchange_format_length);
00587     if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGQTABLES))
00588     {
00589         fprintf(fd,"  JpegQTables:");
00590         for (m=0; m<sp->qtable_offset_count; m++)
00591             fprintf(fd," %lu",(unsigned long)sp->qtable_offset[m]);
00592         fprintf(fd,"\n");
00593     }
00594     if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGDCTABLES))
00595     {
00596         fprintf(fd,"  JpegDcTables:");
00597         for (m=0; m<sp->dctable_offset_count; m++)
00598             fprintf(fd," %lu",(unsigned long)sp->dctable_offset[m]);
00599         fprintf(fd,"\n");
00600     }
00601     if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGACTABLES))
00602     {
00603         fprintf(fd,"  JpegAcTables:");
00604         for (m=0; m<sp->actable_offset_count; m++)
00605             fprintf(fd," %lu",(unsigned long)sp->actable_offset[m]);
00606         fprintf(fd,"\n");
00607     }
00608     if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGPROC))
00609         fprintf(fd,"  JpegProc: %u\n",(unsigned int)sp->jpeg_proc);
00610     if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGRESTARTINTERVAL))
00611         fprintf(fd,"  JpegRestartInterval: %u\n",(unsigned int)sp->restart_interval);
00612 }
00613 
00614 static int
00615 OJPEGSetupDecode(TIFF* tif)
00616 {
00617     static const char module[]="OJPEGSetupDecode";
00618     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");
00619     return(1);
00620 }
00621 
00622 static int
00623 OJPEGPreDecode(TIFF* tif, tsample_t s)
00624 {
00625     OJPEGState* sp=(OJPEGState*)tif->tif_data;
00626     tstrile_t m;
00627     if (sp->subsamplingcorrect_done==0)
00628         OJPEGSubsamplingCorrect(tif);
00629     if (sp->readheader_done==0)
00630     {
00631         if (OJPEGReadHeaderInfo(tif)==0)
00632             return(0);
00633     }
00634     if (sp->sos_end[s].log==0)
00635     {
00636         if (OJPEGReadSecondarySos(tif,s)==0)
00637             return(0);
00638     }
00639     if isTiled(tif)
00640         m=(tstrile_t)tif->tif_curtile;
00641     else
00642         m=(tstrile_t)tif->tif_curstrip;
00643     if ((sp->writeheader_done!=0) && ((sp->write_cursample!=s) || (sp->write_curstrile>m)))
00644     {
00645         if (sp->libjpeg_session_active!=0)
00646             OJPEGLibjpegSessionAbort(tif);
00647         sp->writeheader_done=0;
00648     }
00649     if (sp->writeheader_done==0)
00650     {
00651         sp->plane_sample_offset=s;
00652         sp->write_cursample=s;
00653         sp->write_curstrile=s*tif->tif_dir.td_stripsperimage;
00654         if ((sp->in_buffer_file_pos_log==0) ||
00655             (sp->in_buffer_file_pos-sp->in_buffer_togo!=sp->sos_end[s].in_buffer_file_pos))
00656         {
00657             sp->in_buffer_source=sp->sos_end[s].in_buffer_source;
00658             sp->in_buffer_next_strile=sp->sos_end[s].in_buffer_next_strile;
00659             sp->in_buffer_file_pos=sp->sos_end[s].in_buffer_file_pos;
00660             sp->in_buffer_file_pos_log=0;
00661             sp->in_buffer_file_togo=sp->sos_end[s].in_buffer_file_togo;
00662             sp->in_buffer_togo=0;
00663             sp->in_buffer_cur=0;
00664         }
00665         if (OJPEGWriteHeaderInfo(tif)==0)
00666             return(0);
00667     }
00668     while (sp->write_curstrile<m)          
00669     {
00670         if (sp->libjpeg_jpeg_query_style==0)
00671         {
00672             if (OJPEGPreDecodeSkipRaw(tif)==0)
00673                 return(0);
00674         }
00675         else
00676         {
00677             if (OJPEGPreDecodeSkipScanlines(tif)==0)
00678                 return(0);
00679         }
00680         sp->write_curstrile++;
00681     }
00682     return(1);
00683 }
00684 
00685 static int
00686 OJPEGPreDecodeSkipRaw(TIFF* tif)
00687 {
00688     OJPEGState* sp=(OJPEGState*)tif->tif_data;
00689     uint32 m;
00690     m=sp->lines_per_strile;
00691     if (sp->subsampling_convert_state!=0)
00692     {
00693         if (sp->subsampling_convert_clines-sp->subsampling_convert_state>=m)
00694         {
00695             sp->subsampling_convert_state+=m;
00696             if (sp->subsampling_convert_state==sp->subsampling_convert_clines)
00697                 sp->subsampling_convert_state=0;
00698             return(1);
00699         }
00700         m-=sp->subsampling_convert_clines-sp->subsampling_convert_state;
00701         sp->subsampling_convert_state=0;
00702     }
00703     while (m>=sp->subsampling_convert_clines)
00704     {
00705         if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
00706             return(0);
00707         m-=sp->subsampling_convert_clines;
00708     }
00709     if (m>0)
00710     {
00711         if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
00712             return(0);
00713         sp->subsampling_convert_state=m;
00714     }
00715     return(1);
00716 }
00717 
00718 static int
00719 OJPEGPreDecodeSkipScanlines(TIFF* tif)
00720 {
00721     static const char module[]="OJPEGPreDecodeSkipScanlines";
00722     OJPEGState* sp=(OJPEGState*)tif->tif_data;
00723     uint32 m;
00724     if (sp->skip_buffer==NULL)
00725     {
00726         sp->skip_buffer=_TIFFmalloc(sp->bytes_per_line);
00727         if (sp->skip_buffer==NULL)
00728         {
00729             TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
00730             return(0);
00731         }
00732     }
00733     for (m=0; m<sp->lines_per_strile; m++)
00734     {
00735         if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&sp->skip_buffer,1)==0)
00736             return(0);
00737     }
00738     return(1);
00739 }
00740 
00741 static int
00742 OJPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
00743 {
00744     OJPEGState* sp=(OJPEGState*)tif->tif_data;
00745     (void)s;
00746     if (sp->libjpeg_jpeg_query_style==0)
00747     {
00748         if (OJPEGDecodeRaw(tif,buf,cc)==0)
00749             return(0);
00750     }
00751     else
00752     {
00753         if (OJPEGDecodeScanlines(tif,buf,cc)==0)
00754             return(0);
00755     }
00756     return(1);
00757 }
00758 
00759 static int
00760 OJPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc)
00761 {
00762     static const char module[]="OJPEGDecodeRaw";
00763     OJPEGState* sp=(OJPEGState*)tif->tif_data;
00764     uint8* m;
00765     uint32 n;
00766     uint8* oy;
00767     uint8* ocb;
00768     uint8* ocr;
00769     uint8* p;
00770     uint32 q;
00771     uint8* r;
00772     uint8 sx,sy;
00773     if (cc%sp->bytes_per_line!=0)
00774     {
00775         TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read");
00776         return(0);
00777     }
00778     assert(cc>0);
00779     m=buf;
00780     n=cc;
00781     do
00782     {
00783         if (sp->subsampling_convert_state==0)
00784         {
00785             if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
00786                 return(0);
00787         }
00788         oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen;
00789         ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
00790         ocr=sp->subsampling_convert_crbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
00791         p=m;
00792         for (q=0; q<sp->subsampling_convert_clinelenout; q++)
00793         {
00794             r=oy;
00795             for (sy=0; sy<sp->subsampling_ver; sy++)
00796             {
00797                 for (sx=0; sx<sp->subsampling_hor; sx++)
00798                     *p++=*r++;
00799                 r+=sp->subsampling_convert_ylinelen-sp->subsampling_hor;
00800             }
00801             oy+=sp->subsampling_hor;
00802             *p++=*ocb++;
00803             *p++=*ocr++;
00804         }
00805         sp->subsampling_convert_state++;
00806         if (sp->subsampling_convert_state==sp->subsampling_convert_clines)
00807             sp->subsampling_convert_state=0;
00808         m+=sp->bytes_per_line;
00809         n-=sp->bytes_per_line;
00810     } while(n>0);
00811     return(1);
00812 }
00813 
00814 static int
00815 OJPEGDecodeScanlines(TIFF* tif, tidata_t buf, tsize_t cc)
00816 {
00817     static const char module[]="OJPEGDecodeScanlines";
00818     OJPEGState* sp=(OJPEGState*)tif->tif_data;
00819     uint8* m;
00820     uint32 n;
00821     if (cc%sp->bytes_per_line!=0)
00822     {
00823         TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read");
00824         return(0);
00825     }
00826     assert(cc>0);
00827     m=buf;
00828     n=cc;
00829     do
00830     {
00831         if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&m,1)==0)
00832             return(0);
00833         m+=sp->bytes_per_line;
00834         n-=sp->bytes_per_line;
00835     } while(n>0);
00836     return(1);
00837 }
00838 
00839 static void
00840 OJPEGPostDecode(TIFF* tif, tidata_t buf, tsize_t cc)
00841 {
00842     OJPEGState* sp=(OJPEGState*)tif->tif_data;
00843     (void)buf;
00844     (void)cc;
00845     sp->write_curstrile++;
00846     if (sp->write_curstrile%tif->tif_dir.td_stripsperimage==0)
00847     {
00848         assert(sp->libjpeg_session_active!=0);
00849         OJPEGLibjpegSessionAbort(tif);
00850         sp->writeheader_done=0;
00851     }
00852 }
00853 
00854 static int
00855 OJPEGSetupEncode(TIFF* tif)
00856 {
00857     static const char module[]="OJPEGSetupEncode";
00858     TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
00859     return(0);
00860 }
00861 
00862 static int
00863 OJPEGPreEncode(TIFF* tif, tsample_t s)
00864 {
00865     static const char module[]="OJPEGPreEncode";
00866     (void)s;
00867     TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
00868     return(0);
00869 }
00870 
00871 static int
00872 OJPEGEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
00873 {
00874     static const char module[]="OJPEGEncode";
00875     (void)buf;
00876     (void)cc;
00877     (void)s;
00878     TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
00879     return(0);
00880 }
00881 
00882 static int
00883 OJPEGPostEncode(TIFF* tif)
00884 {
00885     static const char module[]="OJPEGPostEncode";
00886     TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
00887     return(0);
00888 }
00889 
00890 static void
00891 OJPEGCleanup(TIFF* tif)
00892 {
00893     OJPEGState* sp=(OJPEGState*)tif->tif_data;
00894     if (sp!=0)
00895     {
00896         tif->tif_tagmethods.vgetfield=sp->vgetparent;
00897         tif->tif_tagmethods.vsetfield=sp->vsetparent;
00898         if (sp->qtable[0]!=0)
00899             _TIFFfree(sp->qtable[0]);
00900         if (sp->qtable[1]!=0)
00901             _TIFFfree(sp->qtable[1]);
00902         if (sp->qtable[2]!=0)
00903             _TIFFfree(sp->qtable[2]);
00904         if (sp->qtable[3]!=0)
00905             _TIFFfree(sp->qtable[3]);
00906         if (sp->dctable[0]!=0)
00907             _TIFFfree(sp->dctable[0]);
00908         if (sp->dctable[1]!=0)
00909             _TIFFfree(sp->dctable[1]);
00910         if (sp->dctable[2]!=0)
00911             _TIFFfree(sp->dctable[2]);
00912         if (sp->dctable[3]!=0)
00913             _TIFFfree(sp->dctable[3]);
00914         if (sp->actable[0]!=0)
00915             _TIFFfree(sp->actable[0]);
00916         if (sp->actable[1]!=0)
00917             _TIFFfree(sp->actable[1]);
00918         if (sp->actable[2]!=0)
00919             _TIFFfree(sp->actable[2]);
00920         if (sp->actable[3]!=0)
00921             _TIFFfree(sp->actable[3]);
00922         if (sp->libjpeg_session_active!=0)
00923             OJPEGLibjpegSessionAbort(tif);
00924         if (sp->subsampling_convert_ycbcrbuf!=0)
00925             _TIFFfree(sp->subsampling_convert_ycbcrbuf);
00926         if (sp->subsampling_convert_ycbcrimage!=0)
00927             _TIFFfree(sp->subsampling_convert_ycbcrimage);
00928         if (sp->skip_buffer!=0)
00929             _TIFFfree(sp->skip_buffer);
00930         _TIFFfree(sp);
00931         tif->tif_data=NULL;
00932         _TIFFSetDefaultCompressionState(tif);
00933     }
00934 }
00935 
00936 static void
00937 OJPEGSubsamplingCorrect(TIFF* tif)
00938 {
00939     static const char module[]="OJPEGSubsamplingCorrect";
00940     OJPEGState* sp=(OJPEGState*)tif->tif_data;
00941     uint8 mh;
00942     uint8 mv;
00943     assert(sp->subsamplingcorrect_done==0);
00944     if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) &&
00945         (tif->tif_dir.td_photometric!=PHOTOMETRIC_ITULAB)))
00946     {
00947         if (sp->subsampling_tag!=0)
00948             TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag not appropriate for this Photometric and/or SamplesPerPixel");
00949         sp->subsampling_hor=1;
00950         sp->subsampling_ver=1;
00951         sp->subsampling_force_desubsampling_inside_decompression=0;
00952     }
00953     else
00954     {
00955         sp->subsamplingcorrect_done=1;
00956         mh=sp->subsampling_hor;
00957         mv=sp->subsampling_ver;
00958         sp->subsamplingcorrect=1;
00959         OJPEGReadHeaderInfoSec(tif);
00960         if (sp->subsampling_force_desubsampling_inside_decompression!=0)
00961         {
00962             sp->subsampling_hor=1;
00963             sp->subsampling_ver=1;
00964         }
00965         sp->subsamplingcorrect=0;
00966         if (((sp->subsampling_hor!=mh) || (sp->subsampling_ver!=mv)) && (sp->subsampling_force_desubsampling_inside_decompression==0))
00967         {
00968             if (sp->subsampling_tag==0)
00969                 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);
00970             else
00971                 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);
00972         }
00973         if (sp->subsampling_force_desubsampling_inside_decompression!=0)
00974         {
00975             if (sp->subsampling_tag==0)
00976                 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");
00977             else
00978                 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);
00979         }
00980         if (sp->subsampling_force_desubsampling_inside_decompression==0)
00981         {
00982             if (sp->subsampling_hor<sp->subsampling_ver)
00983                 TIFFWarningExt(tif->tif_clientdata,module,"Subsampling values [%d,%d] are not allowed in TIFF",sp->subsampling_hor,sp->subsampling_ver);
00984         }
00985     }
00986     sp->subsamplingcorrect_done=1;
00987 }
00988 
00989 static int
00990 OJPEGReadHeaderInfo(TIFF* tif)
00991 {
00992     static const char module[]="OJPEGReadHeaderInfo";
00993     OJPEGState* sp=(OJPEGState*)tif->tif_data;
00994     assert(sp->readheader_done==0);
00995     sp->image_width=tif->tif_dir.td_imagewidth;
00996     sp->image_length=tif->tif_dir.td_imagelength;
00997     if isTiled(tif)
00998     {
00999         sp->strile_width=tif->tif_dir.td_tilewidth;
01000         sp->strile_length=tif->tif_dir.td_tilelength;
01001         sp->strile_length_total=((sp->image_length+sp->strile_length-1)/sp->strile_length)*sp->strile_length;
01002     }
01003     else
01004     {
01005         sp->strile_width=sp->image_width;
01006         sp->strile_length=tif->tif_dir.td_rowsperstrip;
01007         sp->strile_length_total=sp->image_length;
01008     }
01009     sp->samples_per_pixel=tif->tif_dir.td_samplesperpixel;
01010     if (sp->samples_per_pixel==1)
01011     {
01012         sp->plane_sample_offset=0;
01013         sp->samples_per_pixel_per_plane=sp->samples_per_pixel;
01014         sp->subsampling_hor=1;
01015         sp->subsampling_ver=1;
01016     }
01017     else
01018     {
01019         if (sp->samples_per_pixel!=3)
01020         {
01021             TIFFErrorExt(tif->tif_clientdata,module,"SamplesPerPixel %d not supported for this compression scheme",sp->samples_per_pixel);
01022             return(0);
01023         }
01024         sp->plane_sample_offset=0;
01025         if (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)
01026             sp->samples_per_pixel_per_plane=3;
01027         else
01028             sp->samples_per_pixel_per_plane=1;
01029     }
01030     if (sp->strile_length<sp->image_length)
01031     {
01032         if (sp->strile_length%(sp->subsampling_ver*8)!=0)
01033         {
01034             TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and image strip/tile length");
01035             return(0);
01036         }
01037         sp->restart_interval=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8))*(sp->strile_length/(sp->subsampling_ver*8));
01038     }
01039     if (OJPEGReadHeaderInfoSec(tif)==0)
01040         return(0);
01041     sp->sos_end[0].log=1;
01042     sp->sos_end[0].in_buffer_source=sp->in_buffer_source;
01043     sp->sos_end[0].in_buffer_next_strile=sp->in_buffer_next_strile;
01044     sp->sos_end[0].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo;
01045     sp->sos_end[0].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo;
01046     sp->readheader_done=1;
01047     return(1);
01048 }
01049 
01050 static int
01051 OJPEGReadSecondarySos(TIFF* tif, tsample_t s)
01052 {
01053     OJPEGState* sp=(OJPEGState*)tif->tif_data;
01054     uint8 m;
01055     assert(s>0);
01056     assert(s<3);
01057     assert(sp->sos_end[0].log!=0);
01058     assert(sp->sos_end[s].log==0);
01059     sp->plane_sample_offset=s-1;
01060     while(sp->sos_end[sp->plane_sample_offset].log==0)
01061         sp->plane_sample_offset--;
01062     sp->in_buffer_source=sp->sos_end[sp->plane_sample_offset].in_buffer_source;
01063     sp->in_buffer_next_strile=sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile;
01064     sp->in_buffer_file_pos=sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos;  
01065     sp->in_buffer_file_pos_log=0;
01066     sp->in_buffer_file_togo=sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo;
01067     sp->in_buffer_togo=0;
01068     sp->in_buffer_cur=0;
01069     while(sp->plane_sample_offset<s)
01070     {
01071         do
01072         {
01073             if (OJPEGReadByte(sp,&m)==0)
01074                 return(0);
01075             if (m==255)
01076             {
01077                 do
01078                 {
01079                     if (OJPEGReadByte(sp,&m)==0)
01080                         return(0);
01081                     if (m!=255)
01082                         break;
01083                 } while(1);
01084                 if (m==JPEG_MARKER_SOS)
01085                     break;
01086             }
01087         } while(1);
01088         sp->plane_sample_offset++;
01089         if (OJPEGReadHeaderInfoSecStreamSos(tif)==0)
01090             return(0);
01091         sp->sos_end[sp->plane_sample_offset].log=1;
01092         sp->sos_end[sp->plane_sample_offset].in_buffer_source=sp->in_buffer_source;
01093         sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile=sp->in_buffer_next_strile;
01094         sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo;
01095         sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo;
01096     }
01097     return(1);
01098 }
01099 
01100 static int
01101 OJPEGWriteHeaderInfo(TIFF* tif)
01102 {
01103     static const char module[]="OJPEGWriteHeaderInfo";
01104     OJPEGState* sp=(OJPEGState*)tif->tif_data;
01105     uint8** m;
01106     uint32 n;
01107     assert(sp->libjpeg_session_active==0);
01108     sp->out_state=ososSoi;
01109     sp->restart_index=0;
01110     jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr));
01111     sp->libjpeg_jpeg_error_mgr.output_message=OJPEGLibjpegJpegErrorMgrOutputMessage;
01112     sp->libjpeg_jpeg_error_mgr.error_exit=OJPEGLibjpegJpegErrorMgrErrorExit;
01113     sp->libjpeg_jpeg_decompress_struct.err=&(sp->libjpeg_jpeg_error_mgr);
01114     sp->libjpeg_jpeg_decompress_struct.client_data=(void*)tif;
01115     if (jpeg_create_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
01116         return(0);
01117     sp->libjpeg_session_active=1;
01118     sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=0;
01119     sp->libjpeg_jpeg_source_mgr.init_source=OJPEGLibjpegJpegSourceMgrInitSource;
01120     sp->libjpeg_jpeg_source_mgr.fill_input_buffer=OJPEGLibjpegJpegSourceMgrFillInputBuffer;
01121     sp->libjpeg_jpeg_source_mgr.skip_input_data=OJPEGLibjpegJpegSourceMgrSkipInputData;
01122     sp->libjpeg_jpeg_source_mgr.resync_to_restart=OJPEGLibjpegJpegSourceMgrResyncToRestart;
01123     sp->libjpeg_jpeg_source_mgr.term_source=OJPEGLibjpegJpegSourceMgrTermSource;
01124     sp->libjpeg_jpeg_decompress_struct.src=&(sp->libjpeg_jpeg_source_mgr);
01125     if (jpeg_read_header_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),1)==0)
01126         return(0);
01127     if ((sp->subsampling_force_desubsampling_inside_decompression==0) && (sp->samples_per_pixel_per_plane>1))
01128     {
01129         sp->libjpeg_jpeg_decompress_struct.raw_data_out=1;
01130 #if JPEG_LIB_VERSION >= 70
01131         sp->libjpeg_jpeg_decompress_struct.do_fancy_upsampling=FALSE;
01132 #endif
01133         sp->libjpeg_jpeg_query_style=0;
01134         if (sp->subsampling_convert_log==0)
01135         {
01136             assert(sp->subsampling_convert_ycbcrbuf==0);
01137             assert(sp->subsampling_convert_ycbcrimage==0);
01138             sp->subsampling_convert_ylinelen=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8)*sp->subsampling_hor*8);
01139             sp->subsampling_convert_ylines=sp->subsampling_ver*8;
01140             sp->subsampling_convert_clinelen=sp->subsampling_convert_ylinelen/sp->subsampling_hor;
01141             sp->subsampling_convert_clines=8;
01142             sp->subsampling_convert_ybuflen=sp->subsampling_convert_ylinelen*sp->subsampling_convert_ylines;
01143             sp->subsampling_convert_cbuflen=sp->subsampling_convert_clinelen*sp->subsampling_convert_clines;
01144             sp->subsampling_convert_ycbcrbuflen=sp->subsampling_convert_ybuflen+2*sp->subsampling_convert_cbuflen;
01145             sp->subsampling_convert_ycbcrbuf=_TIFFmalloc(sp->subsampling_convert_ycbcrbuflen);
01146             if (sp->subsampling_convert_ycbcrbuf==0)
01147             {
01148                 TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
01149                 return(0);
01150             }
01151             sp->subsampling_convert_ybuf=sp->subsampling_convert_ycbcrbuf;
01152             sp->subsampling_convert_cbbuf=sp->subsampling_convert_ybuf+sp->subsampling_convert_ybuflen;
01153             sp->subsampling_convert_crbuf=sp->subsampling_convert_cbbuf+sp->subsampling_convert_cbuflen;
01154             sp->subsampling_convert_ycbcrimagelen=3+sp->subsampling_convert_ylines+2*sp->subsampling_convert_clines;
01155             sp->subsampling_convert_ycbcrimage=_TIFFmalloc(sp->subsampling_convert_ycbcrimagelen*sizeof(uint8*));
01156             if (sp->subsampling_convert_ycbcrimage==0)
01157             {
01158                 TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
01159                 return(0);
01160             }
01161             m=sp->subsampling_convert_ycbcrimage;
01162             *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3);
01163             *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines);
01164             *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines+sp->subsampling_convert_clines);
01165             for (n=0; n<sp->subsampling_convert_ylines; n++)
01166                 *m++=sp->subsampling_convert_ybuf+n*sp->subsampling_convert_ylinelen;
01167             for (n=0; n<sp->subsampling_convert_clines; n++)
01168                 *m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen;
01169             for (n=0; n<sp->subsampling_convert_clines; n++)
01170                 *m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen;
01171             sp->subsampling_convert_clinelenout=((sp->strile_width+sp->subsampling_hor-1)/sp->subsampling_hor);
01172             sp->subsampling_convert_state=0;
01173             sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2);
01174             sp->lines_per_strile=((sp->strile_length+sp->subsampling_ver-1)/sp->subsampling_ver);
01175             sp->subsampling_convert_log=1;
01176         }
01177     }
01178     else
01179     {
01180         sp->libjpeg_jpeg_decompress_struct.jpeg_color_space=JCS_UNKNOWN;
01181         sp->libjpeg_jpeg_decompress_struct.out_color_space=JCS_UNKNOWN;
01182         sp->libjpeg_jpeg_query_style=1;
01183         sp->bytes_per_line=sp->samples_per_pixel_per_plane*sp->strile_width;
01184         sp->lines_per_strile=sp->strile_length;
01185     }
01186     if (jpeg_start_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
01187         return(0);
01188     sp->writeheader_done=1;
01189     return(1);
01190 }
01191 
01192 static void
01193 OJPEGLibjpegSessionAbort(TIFF* tif)
01194 {
01195     OJPEGState* sp=(OJPEGState*)tif->tif_data;
01196     assert(sp->libjpeg_session_active!=0);
01197     jpeg_destroy((jpeg_common_struct*)(&(sp->libjpeg_jpeg_decompress_struct)));
01198     sp->libjpeg_session_active=0;
01199 }
01200 
01201 static int
01202 OJPEGReadHeaderInfoSec(TIFF* tif)
01203 {
01204     static const char module[]="OJPEGReadHeaderInfoSec";
01205     OJPEGState* sp=(OJPEGState*)tif->tif_data;
01206     uint8 m;
01207     uint16 n;
01208     uint8 o;
01209     if (sp->file_size==0)
01210         sp->file_size=TIFFGetFileSize(tif);
01211     if (sp->jpeg_interchange_format!=0)
01212     {
01213         if (sp->jpeg_interchange_format>=sp->file_size)
01214         {
01215             sp->jpeg_interchange_format=0;
01216             sp->jpeg_interchange_format_length=0;
01217         }
01218         else
01219         {
01220             if ((sp->jpeg_interchange_format_length==0) || (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size))
01221                 sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format;
01222         }
01223     }
01224     sp->in_buffer_source=osibsNotSetYet;
01225     sp->in_buffer_next_strile=0;
01226     sp->in_buffer_strile_count=tif->tif_dir.td_nstrips;   
01227     sp->in_buffer_file_togo=0;
01228     sp->in_buffer_togo=0;
01229     do
01230     {
01231         if (OJPEGReadBytePeek(sp,&m)==0)
01232             return(0);
01233         if (m!=255)
01234             break;
01235         OJPEGReadByteAdvance(sp);
01236         do
01237         {
01238             if (OJPEGReadByte(sp,&m)==0)
01239                 return(0);
01240         } while(m==255);
01241         switch(m)
01242         {
01243             case JPEG_MARKER_SOI:
01244                 /* this type of marker has no data, and should be skipped */
01245                 break;
01246             case JPEG_MARKER_COM:
01247             case JPEG_MARKER_APP0:
01248             case JPEG_MARKER_APP0+1:
01249             case JPEG_MARKER_APP0+2:
01250             case JPEG_MARKER_APP0+3:
01251             case JPEG_MARKER_APP0+4:
01252             case JPEG_MARKER_APP0+5:
01253             case JPEG_MARKER_APP0+6:
01254             case JPEG_MARKER_APP0+7:
01255             case JPEG_MARKER_APP0+8:
01256             case JPEG_MARKER_APP0+9:
01257             case JPEG_MARKER_APP0+10:
01258             case JPEG_MARKER_APP0+11:
01259             case JPEG_MARKER_APP0+12:
01260             case JPEG_MARKER_APP0+13:
01261             case JPEG_MARKER_APP0+14:
01262             case JPEG_MARKER_APP0+15:
01263                 /* this type of marker has data, but it has no use to us (and no place here) and should be skipped */
01264                 if (OJPEGReadWord(sp,&n)==0)
01265                     return(0);
01266                 if (n<2)
01267                 {
01268                     if (sp->subsamplingcorrect==0)
01269                         TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
01270                     return(0);
01271                 }
01272                 if (n>2)
01273                     OJPEGReadSkip(sp,n-2);
01274                 break;
01275             case JPEG_MARKER_DRI:
01276                 if (OJPEGReadHeaderInfoSecStreamDri(tif)==0)
01277                     return(0);
01278                 break;
01279             case JPEG_MARKER_DQT:
01280                 if (OJPEGReadHeaderInfoSecStreamDqt(tif)==0)
01281                     return(0);
01282                 break;
01283             case JPEG_MARKER_DHT:
01284                 if (OJPEGReadHeaderInfoSecStreamDht(tif)==0)
01285                     return(0);
01286                 break;
01287             case JPEG_MARKER_SOF0:
01288             case JPEG_MARKER_SOF1:
01289             case JPEG_MARKER_SOF3:
01290                 if (OJPEGReadHeaderInfoSecStreamSof(tif,m)==0)
01291                     return(0);
01292                 if (sp->subsamplingcorrect!=0)
01293                     return(1);
01294                 break;
01295             case JPEG_MARKER_SOS:
01296                 if (sp->subsamplingcorrect!=0)
01297                     return(1);
01298                 assert(sp->plane_sample_offset==0);
01299                 if (OJPEGReadHeaderInfoSecStreamSos(tif)==0)
01300                     return(0);
01301                 break;
01302             default:
01303                 TIFFErrorExt(tif->tif_clientdata,module,"Unknown marker type %d in JPEG data",m);
01304                 return(0);
01305         }
01306     } while(m!=JPEG_MARKER_SOS);
01307     if (sp->subsamplingcorrect)
01308         return(1);
01309     if (sp->sof_log==0)
01310     {
01311         if (OJPEGReadHeaderInfoSecTablesQTable(tif)==0)
01312             return(0);
01313         sp->sof_marker_id=JPEG_MARKER_SOF0;
01314         for (o=0; o<sp->samples_per_pixel; o++)
01315             sp->sof_c[o]=o;
01316         sp->sof_hv[0]=((sp->subsampling_hor<<4)|sp->subsampling_ver);
01317         for (o=1; o<sp->samples_per_pixel; o++)
01318             sp->sof_hv[o]=17;
01319         sp->sof_x=sp->strile_width;
01320         sp->sof_y=sp->strile_length_total;
01321         sp->sof_log=1;
01322         if (OJPEGReadHeaderInfoSecTablesDcTable(tif)==0)
01323             return(0);
01324         if (OJPEGReadHeaderInfoSecTablesAcTable(tif)==0)
01325             return(0);
01326         for (o=1; o<sp->samples_per_pixel; o++)
01327             sp->sos_cs[o]=o;
01328     }
01329     return(1);
01330 }
01331 
01332 static int
01333 OJPEGReadHeaderInfoSecStreamDri(TIFF* tif)
01334 {
01335     /* this could easilly cause trouble in some cases... but no such cases have occured sofar */
01336     static const char module[]="OJPEGReadHeaderInfoSecStreamDri";
01337     OJPEGState* sp=(OJPEGState*)tif->tif_data;
01338     uint16 m;
01339     if (OJPEGReadWord(sp,&m)==0)
01340         return(0);
01341     if (m!=4)
01342     {
01343         TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DRI marker in JPEG data");
01344         return(0);
01345     }
01346     if (OJPEGReadWord(sp,&m)==0)
01347         return(0);
01348     sp->restart_interval=m;
01349     return(1);
01350 }
01351 
01352 static int
01353 OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif)
01354 {
01355     /* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */
01356     static const char module[]="OJPEGReadHeaderInfoSecStreamDqt";
01357     OJPEGState* sp=(OJPEGState*)tif->tif_data;
01358     uint16 m;
01359     uint32 na;
01360     uint8* nb;
01361     uint8 o;
01362     if (OJPEGReadWord(sp,&m)==0)
01363         return(0);
01364     if (m<=2)
01365     {
01366         if (sp->subsamplingcorrect==0)
01367             TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
01368         return(0);
01369     }
01370     if (sp->subsamplingcorrect!=0)
01371         OJPEGReadSkip(sp,m-2);
01372     else
01373     {
01374         m-=2;
01375         do
01376         {
01377             if (m<65)
01378             {
01379                 TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
01380                 return(0);
01381             }
01382             na=sizeof(uint32)+69;
01383             nb=_TIFFmalloc(na);
01384             if (nb==0)
01385             {
01386                 TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
01387                 return(0);
01388             }
01389             *(uint32*)nb=na;
01390             nb[sizeof(uint32)]=255;
01391             nb[sizeof(uint32)+1]=JPEG_MARKER_DQT;
01392             nb[sizeof(uint32)+2]=0;
01393             nb[sizeof(uint32)+3]=67;
01394             if (OJPEGReadBlock(sp,65,&nb[sizeof(uint32)+4])==0)
01395                 return(0);
01396             o=nb[sizeof(uint32)+4]&15;
01397             if (3<o)
01398             {
01399                 TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
01400                 return(0);
01401             }
01402             if (sp->qtable[o]!=0)
01403                 _TIFFfree(sp->qtable[o]);
01404             sp->qtable[o]=nb;
01405             m-=65;
01406         } while(m>0);
01407     }
01408     return(1);
01409 }
01410 
01411 static int
01412 OJPEGReadHeaderInfoSecStreamDht(TIFF* tif)
01413 {
01414     /* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */
01415     /* TODO: the following assumes there is only one table in this marker... but i'm not quite sure that assumption is guaranteed correct */
01416     static const char module[]="OJPEGReadHeaderInfoSecStreamDht";
01417     OJPEGState* sp=(OJPEGState*)tif->tif_data;
01418     uint16 m;
01419     uint32 na;
01420     uint8* nb;
01421     uint8 o;
01422     if (OJPEGReadWord(sp,&m)==0)
01423         return(0);
01424     if (m<=2)
01425     {
01426         if (sp->subsamplingcorrect==0)
01427             TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
01428         return(0);
01429     }
01430     if (sp->subsamplingcorrect!=0)
01431     {
01432         OJPEGReadSkip(sp,m-2);
01433     }
01434     else
01435     {
01436         na=sizeof(uint32)+2+m;
01437         nb=_TIFFmalloc(na);
01438         if (nb==0)
01439         {
01440             TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
01441             return(0);
01442         }
01443         *(uint32*)nb=na;
01444         nb[sizeof(uint32)]=255;
01445         nb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
01446         nb[sizeof(uint32)+2]=(m>>8);
01447         nb[sizeof(uint32)+3]=(m&255);
01448         if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0)
01449             return(0);
01450         o=nb[sizeof(uint32)+4];
01451         if ((o&240)==0)
01452         {
01453             if (3<o)
01454             {
01455                 TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
01456                 return(0);
01457             }
01458             if (sp->dctable[o]!=0)
01459                 _TIFFfree(sp->dctable[o]);
01460             sp->dctable[o]=nb;
01461         }
01462         else
01463         {
01464             if ((o&240)!=16)
01465             {
01466                 TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
01467                 return(0);
01468             }
01469             o&=15;
01470             if (3<o)
01471             {
01472                 TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
01473                 return(0);
01474             }
01475             if (sp->actable[o]!=0)
01476                 _TIFFfree(sp->actable[o]);
01477             sp->actable[o]=nb;
01478         }
01479     }
01480     return(1);
01481 }
01482 
01483 static int
01484 OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id)
01485 {
01486     /* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
01487     static const char module[]="OJPEGReadHeaderInfoSecStreamSof";
01488     OJPEGState* sp=(OJPEGState*)tif->tif_data;
01489     uint16 m;
01490     uint16 n;
01491     uint8 o;
01492     uint16 p;
01493     uint16 q;
01494     if (sp->sof_log!=0)
01495     {
01496         TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
01497         return(0);
01498     }
01499     if (sp->subsamplingcorrect==0)
01500         sp->sof_marker_id=marker_id;
01501     /* Lf: data length */
01502     if (OJPEGReadWord(sp,&m)==0)
01503         return(0);
01504     if (m<11)
01505     {
01506         if (sp->subsamplingcorrect==0)
01507             TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
01508         return(0);
01509     }
01510     m-=8;
01511     if (m%3!=0)
01512     {
01513         if (sp->subsamplingcorrect==0)
01514             TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
01515         return(0);
01516     }
01517     n=m/3;
01518     if (sp->subsamplingcorrect==0)
01519     {
01520         if (n!=sp->samples_per_pixel)
01521         {
01522             TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of samples");
01523             return(0);
01524         }
01525     }
01526     /* P: Sample precision */
01527     if (OJPEGReadByte(sp,&o)==0)
01528         return(0);
01529     if (o!=8)
01530     {
01531         if (sp->subsamplingcorrect==0)
01532             TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of bits per sample");
01533         return(0);
01534     }
01535     /* Y: Number of lines, X: Number of samples per line */
01536     if (sp->subsamplingcorrect)
01537         OJPEGReadSkip(sp,4);
01538     else
01539     {
01540         /* TODO: probably best to also add check on allowed upper bound, especially x, may cause buffer overflow otherwise i think */
01541         /* Y: Number of lines */
01542         if (OJPEGReadWord(sp,&p)==0)
01543             return(0);
01544         if ((p<sp->image_length) && (p<sp->strile_length_total))
01545         {
01546             TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected height");
01547             return(0);
01548         }
01549         sp->sof_y=p;
01550         /* X: Number of samples per line */
01551         if (OJPEGReadWord(sp,&p)==0)
01552             return(0);
01553         if ((p<sp->image_width) && (p<sp->strile_width))
01554         {
01555             TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected width");
01556             return(0);
01557         }
01558         sp->sof_x=p;
01559     }
01560     /* Nf: Number of image components in frame */
01561     if (OJPEGReadByte(sp,&o)==0)
01562         return(0);
01563     if (o!=n)
01564     {
01565         if (sp->subsamplingcorrect==0)
01566             TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
01567         return(0);
01568     }
01569     /* per component stuff */
01570     /* 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 */
01571     for (q=0; q<n; q++)
01572     {
01573         /* C: Component identifier */
01574         if (OJPEGReadByte(sp,&o)==0)
01575             return(0);
01576         if (sp->subsamplingcorrect==0)
01577             sp->sof_c[q]=o;
01578         /* H: Horizontal sampling factor, and V: Vertical sampling factor */
01579         if (OJPEGReadByte(sp,&o)==0)
01580             return(0);
01581         if (sp->subsamplingcorrect!=0)
01582         {
01583             if (q==0)
01584             {
01585                 sp->subsampling_hor=(o>>4);
01586                 sp->subsampling_ver=(o&15);
01587                 if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) ||
01588                     ((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4)))
01589                     sp->subsampling_force_desubsampling_inside_decompression=1;
01590             }
01591             else
01592             {
01593                 if (o!=17)
01594                     sp->subsampling_force_desubsampling_inside_decompression=1;
01595             }
01596         }
01597         else
01598         {
01599             sp->sof_hv[q]=o;
01600             if (sp->subsampling_force_desubsampling_inside_decompression==0)
01601             {
01602                 if (q==0)
01603                 {
01604                     if (o!=((sp->subsampling_hor<<4)|sp->subsampling_ver))
01605                     {
01606                         TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
01607                         return(0);
01608                     }
01609                 }
01610                 else
01611                 {
01612                     if (o!=17)
01613                     {
01614                         TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
01615                         return(0);
01616                     }
01617                 }
01618             }
01619         }
01620         /* Tq: Quantization table destination selector */
01621         if (OJPEGReadByte(sp,&o)==0)
01622             return(0);
01623         if (sp->subsamplingcorrect==0)
01624             sp->sof_tq[q]=o;
01625     }
01626     if (sp->subsamplingcorrect==0)
01627         sp->sof_log=1;
01628     return(1);
01629 }
01630 
01631 static int
01632 OJPEGReadHeaderInfoSecStreamSos(TIFF* tif)
01633 {
01634     /* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
01635     static const char module[]="OJPEGReadHeaderInfoSecStreamSos";
01636     OJPEGState* sp=(OJPEGState*)tif->tif_data;
01637     uint16 m;
01638     uint8 n;
01639     uint8 o;
01640     assert(sp->subsamplingcorrect==0);
01641     if (sp->sof_log==0)
01642     {
01643         TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
01644         return(0);
01645     }
01646     /* Ls */
01647     if (OJPEGReadWord(sp,&m)==0)
01648         return(0);
01649     if (m!=6+sp->samples_per_pixel_per_plane*2)
01650     {
01651         TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
01652         return(0);
01653     }
01654     /* Ns */
01655     if (OJPEGReadByte(sp,&n)==0)
01656         return(0);
01657     if (n!=sp->samples_per_pixel_per_plane)
01658     {
01659         TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
01660         return(0);
01661     }
01662     /* Cs, Td, and Ta */
01663     for (o=0; o<sp->samples_per_pixel_per_plane; o++)
01664     {
01665         /* Cs */
01666         if (OJPEGReadByte(sp,&n)==0)
01667             return(0);
01668         sp->sos_cs[sp->plane_sample_offset+o]=n;
01669         /* Td and Ta */
01670         if (OJPEGReadByte(sp,&n)==0)
01671             return(0);
01672         sp->sos_tda[sp->plane_sample_offset+o]=n;
01673     }
01674     /* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as per LibJpeg source */
01675     OJPEGReadSkip(sp,3);
01676     return(1);
01677 }
01678 
01679 static int
01680 OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif)
01681 {
01682     static const char module[]="OJPEGReadHeaderInfoSecTablesQTable";
01683     OJPEGState* sp=(OJPEGState*)tif->tif_data;
01684     uint8 m;
01685     uint8 n;
01686     uint32 oa;
01687     uint8* ob;
01688     uint32 p;
01689     if (sp->qtable_offset[0]==0)
01690     {
01691         TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
01692         return(0);
01693     }
01694     sp->in_buffer_file_pos_log=0;
01695     for (m=0; m<sp->samples_per_pixel; m++)
01696     {
01697         if ((sp->qtable_offset[m]!=0) && ((m==0) || (sp->qtable_offset[m]!=sp->qtable_offset[m-1])))
01698         {
01699             for (n=0; n<m-1; n++)
01700             {
01701                 if (sp->qtable_offset[m]==sp->qtable_offset[n])
01702                 {
01703                     TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegQTables tag value");
01704                     return(0);
01705                 }
01706             }
01707             oa=sizeof(uint32)+69;
01708             ob=_TIFFmalloc(oa);
01709             if (ob==0)
01710             {
01711                 TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
01712                 return(0);
01713             }
01714             *(uint32*)ob=oa;
01715             ob[sizeof(uint32)]=255;
01716             ob[sizeof(uint32)+1]=JPEG_MARKER_DQT;
01717             ob[sizeof(uint32)+2]=0;
01718             ob[sizeof(uint32)+3]=67;
01719             ob[sizeof(uint32)+4]=m;
01720             TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET);
01721             p=TIFFReadFile(tif,&ob[sizeof(uint32)+5],64);
01722             if (p!=64)
01723                 return(0);
01724             sp->qtable[m]=ob;
01725             sp->sof_tq[m]=m;
01726         }
01727         else
01728             sp->sof_tq[m]=sp->sof_tq[m-1];
01729     }
01730     return(1);
01731 }
01732 
01733 static int
01734 OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif)
01735 {
01736     static const char module[]="OJPEGReadHeaderInfoSecTablesDcTable";
01737     OJPEGState* sp=(OJPEGState*)tif->tif_data;
01738     uint8 m;
01739     uint8 n;
01740     uint8 o[16];
01741     uint32 p;
01742     uint32 q;
01743     uint32 ra;
01744     uint8* rb;
01745     if (sp->dctable_offset[0]==0)
01746     {
01747         TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
01748         return(0);
01749     }
01750     sp->in_buffer_file_pos_log=0;
01751     for (m=0; m<sp->samples_per_pixel; m++)
01752     {
01753         if ((sp->dctable_offset[m]!=0) && ((m==0) || (sp->dctable_offset[m]!=sp->dctable_offset[m-1])))
01754         {
01755             for (n=0; n<m-1; n++)
01756             {
01757                 if (sp->dctable_offset[m]==sp->dctable_offset[n])
01758                 {
01759                     TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegDcTables tag value");
01760                     return(0);
01761                 }
01762             }
01763             TIFFSeekFile(tif,sp->dctable_offset[m],SEEK_SET);
01764             p=TIFFReadFile(tif,o,16);
01765             if (p!=16)
01766                 return(0);
01767             q=0;
01768             for (n=0; n<16; n++)
01769                 q+=o[n];
01770             ra=sizeof(uint32)+21+q;
01771             rb=_TIFFmalloc(ra);
01772             if (rb==0)
01773             {
01774                 TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
01775                 return(0);
01776             }
01777             *(uint32*)rb=ra;
01778             rb[sizeof(uint32)]=255;
01779             rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
01780             rb[sizeof(uint32)+2]=((19+q)>>8);
01781             rb[sizeof(uint32)+3]=((19+q)&255);
01782             rb[sizeof(uint32)+4]=m;
01783             for (n=0; n<16; n++)
01784                 rb[sizeof(uint32)+5+n]=o[n];
01785             p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
01786             if (p!=q)
01787                 return(0);
01788             sp->dctable[m]=rb;
01789             sp->sos_tda[m]=(m<<4);
01790         }
01791         else
01792             sp->sos_tda[m]=sp->sos_tda[m-1];
01793     }
01794     return(1);
01795 }
01796 
01797 static int
01798 OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif)
01799 {
01800     static const char module[]="OJPEGReadHeaderInfoSecTablesAcTable";
01801     OJPEGState* sp=(OJPEGState*)tif->tif_data;
01802     uint8 m;
01803     uint8 n;
01804     uint8 o[16];
01805     uint32 p;
01806     uint32 q;
01807     uint32 ra;
01808     uint8* rb;
01809     if (sp->actable_offset[0]==0)
01810     {
01811         TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
01812         return(0);
01813     }
01814     sp->in_buffer_file_pos_log=0;
01815     for (m=0; m<sp->samples_per_pixel; m++)
01816     {
01817         if ((sp->actable_offset[m]!=0) && ((m==0) || (sp->actable_offset[m]!=sp->actable_offset[m-1])))
01818         {
01819             for (n=0; n<m-1; n++)
01820             {
01821                 if (sp->actable_offset[m]==sp->actable_offset[n])
01822                 {
01823                     TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegAcTables tag value");
01824                     return(0);
01825                 }
01826             }
01827             TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET);
01828             p=TIFFReadFile(tif,o,16);
01829             if (p!=16)
01830                 return(0);
01831             q=0;
01832             for (n=0; n<16; n++)
01833                 q+=o[n];
01834             ra=sizeof(uint32)+21+q;
01835             rb=_TIFFmalloc(ra);
01836             if (rb==0)
01837             {
01838                 TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
01839                 return(0);
01840             }
01841             *(uint32*)rb=ra;
01842             rb[sizeof(uint32)]=255;
01843             rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
01844             rb[sizeof(uint32)+2]=((19+q)>>8);
01845             rb[sizeof(uint32)+3]=((19+q)&255);
01846             rb[sizeof(uint32)+4]=(16|m);
01847             for (n=0; n<16; n++)
01848                 rb[sizeof(uint32)+5+n]=o[n];
01849             p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
01850             if (p!=q)
01851                 return(0);
01852             sp->actable[m]=rb;
01853             sp->sos_tda[m]=(sp->sos_tda[m]|m);
01854         }
01855         else
01856             sp->sos_tda[m]=(sp->sos_tda[m]|(sp->sos_tda[m-1]&15));
01857     }
01858     return(1);
01859 }
01860 
01861 static int
01862 OJPEGReadBufferFill(OJPEGState* sp)
01863 {
01864     uint16 m;
01865     tsize_t n;
01866     /* TODO: double-check: when subsamplingcorrect is set, no call to TIFFErrorExt or TIFFWarningExt should be made
01867      * in any other case, seek or read errors should be passed through */
01868     do
01869     {
01870         if (sp->in_buffer_file_togo!=0)
01871         {
01872             if (sp->in_buffer_file_pos_log==0)
01873             {
01874                 TIFFSeekFile(sp->tif,sp->in_buffer_file_pos,SEEK_SET);
01875                 sp->in_buffer_file_pos_log=1;
01876             }
01877             m=OJPEG_BUFFER;
01878             if (m>sp->in_buffer_file_togo)
01879                 m=(uint16)sp->in_buffer_file_togo;
01880             n=TIFFReadFile(sp->tif,sp->in_buffer,(tsize_t)m);
01881             if (n==0)
01882                 return(0);
01883             assert(n>0);
01884             assert(n<=OJPEG_BUFFER);
01885             assert(n<65536);
01886             assert((uint16)n<=sp->in_buffer_file_togo);
01887             m=(uint16)n;
01888             sp->in_buffer_togo=m;
01889             sp->in_buffer_cur=sp->in_buffer;
01890             sp->in_buffer_file_togo-=m;
01891             sp->in_buffer_file_pos+=m;
01892             break;
01893         }
01894         sp->in_buffer_file_pos_log=0;
01895         switch(sp->in_buffer_source)
01896         {
01897             case osibsNotSetYet:
01898                 if (sp->jpeg_interchange_format!=0)
01899                 {
01900                     sp->in_buffer_file_pos=sp->jpeg_interchange_format;
01901                     sp->in_buffer_file_togo=sp->jpeg_interchange_format_length;
01902                 }
01903                 sp->in_buffer_source=osibsJpegInterchangeFormat;
01904                 break;
01905             case osibsJpegInterchangeFormat:
01906                 sp->in_buffer_source=osibsStrile;
01907             case osibsStrile:
01908                 if (sp->in_buffer_next_strile==sp->in_buffer_strile_count)  
01909                     sp->in_buffer_source=osibsEof;
01910                 else
01911                 {
01912                     if (sp->tif->tif_dir.td_stripoffset == 0) {
01913                         TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip offsets are missing");
01914                         return(0);
01915                     }
01916                     sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile];  
01917                     if (sp->in_buffer_file_pos!=0)
01918                     {
01919                         if (sp->in_buffer_file_pos>=sp->file_size)
01920                             sp->in_buffer_file_pos=0;
01921                         else
01922                         {
01923                             sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];  
01924                             if (sp->in_buffer_file_togo==0)
01925                                 sp->in_buffer_file_pos=0;
01926                             else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
01927                                 sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
01928                         }
01929                     }
01930                     sp->in_buffer_next_strile++;
01931                 }
01932                 break;
01933             default:
01934                 return(0);
01935         }
01936     } while (1);
01937     return(1);
01938 }
01939 
01940 static int
01941 OJPEGReadByte(OJPEGState* sp, uint8* byte)
01942 {
01943     if (sp->in_buffer_togo==0)
01944     {
01945         if (OJPEGReadBufferFill(sp)==0)
01946             return(0);
01947         assert(sp->in_buffer_togo>0);
01948     }
01949     *byte=*(sp->in_buffer_cur);
01950     sp->in_buffer_cur++;
01951     sp->in_buffer_togo--;
01952     return(1);
01953 }
01954 
01955 static int
01956 OJPEGReadBytePeek(OJPEGState* sp, uint8* byte)
01957 {
01958     if (sp->in_buffer_togo==0)
01959     {
01960         if (OJPEGReadBufferFill(sp)==0)
01961             return(0);
01962         assert(sp->in_buffer_togo>0);
01963     }
01964     *byte=*(sp->in_buffer_cur);
01965     return(1);
01966 }
01967 
01968 static void
01969 OJPEGReadByteAdvance(OJPEGState* sp)
01970 {
01971     assert(sp->in_buffer_togo>0);
01972     sp->in_buffer_cur++;
01973     sp->in_buffer_togo--;
01974 }
01975 
01976 static int
01977 OJPEGReadWord(OJPEGState* sp, uint16* word)
01978 {
01979     uint8 m;
01980     if (OJPEGReadByte(sp,&m)==0)
01981         return(0);
01982     *word=(m<<8);
01983     if (OJPEGReadByte(sp,&m)==0)
01984         return(0);
01985     *word|=m;
01986     return(1);
01987 }
01988 
01989 static int
01990 OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem)
01991 {
01992     uint16 mlen;
01993     uint8* mmem;
01994     uint16 n;
01995     assert(len>0);
01996     mlen=len;
01997     mmem=mem;
01998     do
01999     {
02000         if (sp->in_buffer_togo==0)
02001         {
02002             if (OJPEGReadBufferFill(sp)==0)
02003                 return(0);
02004             assert(sp->in_buffer_togo>0);
02005         }
02006         n=mlen;
02007         if (n>sp->in_buffer_togo)
02008             n=sp->in_buffer_togo;
02009         _TIFFmemcpy(mmem,sp->in_buffer_cur,n);
02010         sp->in_buffer_cur+=n;
02011         sp->in_buffer_togo-=n;
02012         mlen-=n;
02013         mmem+=n;
02014     } while(mlen>0);
02015     return(1);
02016 }
02017 
02018 static void
02019 OJPEGReadSkip(OJPEGState* sp, uint16 len)
02020 {
02021     uint16 m;
02022     uint16 n;
02023     m=len;
02024     n=m;
02025     if (n>sp->in_buffer_togo)
02026         n=sp->in_buffer_togo;
02027     sp->in_buffer_cur+=n;
02028     sp->in_buffer_togo-=n;
02029     m-=n;
02030     if (m>0)
02031     {
02032         assert(sp->in_buffer_togo==0);
02033         n=m;
02034         if (n>sp->in_buffer_file_togo)
02035             n=sp->in_buffer_file_togo;
02036         sp->in_buffer_file_pos+=n;
02037         sp->in_buffer_file_togo-=n;
02038         sp->in_buffer_file_pos_log=0;
02039         /* we don't skip past jpeginterchangeformat/strile block...
02040          * if that is asked from us, we're dealing with totally bazurk
02041          * data anyway, and we've not seen this happening on any
02042          * testfile, so we might as well likely cause some other
02043          * meaningless error to be passed at some later time
02044          */
02045     }
02046 }
02047 
02048 static int
02049 OJPEGWriteStream(TIFF* tif, void** mem, uint32* len)
02050 {
02051     OJPEGState* sp=(OJPEGState*)tif->tif_data;
02052     *len=0;
02053     do
02054     {
02055         assert(sp->out_state<=ososEoi);
02056         switch(sp->out_state)
02057         {
02058             case ososSoi:
02059                 OJPEGWriteStreamSoi(tif,mem,len);
02060                 break;
02061             case ososQTable0:
02062                 OJPEGWriteStreamQTable(tif,0,mem,len);
02063                 break;
02064             case ososQTable1:
02065                 OJPEGWriteStreamQTable(tif,1,mem,len);
02066                 break;
02067             case ososQTable2:
02068                 OJPEGWriteStreamQTable(tif,2,mem,len);
02069                 break;
02070             case ososQTable3:
02071                 OJPEGWriteStreamQTable(tif,3,mem,len);
02072                 break;
02073             case ososDcTable0:
02074                 OJPEGWriteStreamDcTable(tif,0,mem,len);
02075                 break;
02076             case ososDcTable1:
02077                 OJPEGWriteStreamDcTable(tif,1,mem,len);
02078                 break;
02079             case ososDcTable2:
02080                 OJPEGWriteStreamDcTable(tif,2,mem,len);
02081                 break;
02082             case ososDcTable3:
02083                 OJPEGWriteStreamDcTable(tif,3,mem,len);
02084                 break;
02085             case ososAcTable0:
02086                 OJPEGWriteStreamAcTable(tif,0,mem,len);
02087                 break;
02088             case ososAcTable1:
02089                 OJPEGWriteStreamAcTable(tif,1,mem,len);
02090                 break;
02091             case ososAcTable2:
02092                 OJPEGWriteStreamAcTable(tif,2,mem,len);
02093                 break;
02094             case ososAcTable3:
02095                 OJPEGWriteStreamAcTable(tif,3,mem,len);
02096                 break;
02097             case ososDri:
02098                 OJPEGWriteStreamDri(tif,mem,len);
02099                 break;
02100             case ososSof:
02101                 OJPEGWriteStreamSof(tif,mem,len);
02102                 break;
02103             case ososSos:
02104                 OJPEGWriteStreamSos(tif,mem,len);
02105                 break;
02106             case ososCompressed:
02107                 if (OJPEGWriteStreamCompressed(tif,mem,len)==0)
02108                     return(0);
02109                 break;
02110             case ososRst:
02111                 OJPEGWriteStreamRst(tif,mem,len);
02112                 break;
02113             case ososEoi:
02114                 OJPEGWriteStreamEoi(tif,mem,len);
02115                 break;
02116         }
02117     } while (*len==0);
02118     return(1);
02119 }
02120 
02121 static void
02122 OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len)
02123 {
02124     OJPEGState* sp=(OJPEGState*)tif->tif_data;
02125     assert(OJPEG_BUFFER>=2);
02126     sp->out_buffer[0]=255;
02127     sp->out_buffer[1]=JPEG_MARKER_SOI;
02128     *len=2;
02129     *mem=(void*)sp->out_buffer;
02130     sp->out_state++;
02131 }
02132 
02133 static void
02134 OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
02135 {
02136     OJPEGState* sp=(OJPEGState*)tif->tif_data;
02137     if (sp->qtable[table_index]!=0)
02138     {
02139         *mem=(void*)(sp->qtable[table_index]+sizeof(uint32));
02140         *len=*((uint32*)sp->qtable[table_index])-sizeof(uint32);
02141     }
02142     sp->out_state++;
02143 }
02144 
02145 static void
02146 OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
02147 {
02148     OJPEGState* sp=(OJPEGState*)tif->tif_data;
02149     if (sp->dctable[table_index]!=0)
02150     {
02151         *mem=(void*)(sp->dctable[table_index]+sizeof(uint32));
02152         *len=*((uint32*)sp->dctable[table_index])-sizeof(uint32);
02153     }
02154     sp->out_state++;
02155 }
02156 
02157 static void
02158 OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
02159 {
02160     OJPEGState* sp=(OJPEGState*)tif->tif_data;
02161     if (sp->actable[table_index]!=0)
02162     {
02163         *mem=(void*)(sp->actable[table_index]+sizeof(uint32));
02164         *len=*((uint32*)sp->actable[table_index])-sizeof(uint32);
02165     }
02166     sp->out_state++;
02167 }
02168 
02169 static void
02170 OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len)
02171 {
02172     OJPEGState* sp=(OJPEGState*)tif->tif_data;
02173     assert(OJPEG_BUFFER>=6);
02174     if (sp->restart_interval!=0)
02175     {
02176         sp->out_buffer[0]=255;
02177         sp->out_buffer[1]=JPEG_MARKER_DRI;
02178         sp->out_buffer[2]=0;
02179         sp->out_buffer[3]=4;
02180         sp->out_buffer[4]=(sp->restart_interval>>8);
02181         sp->out_buffer[5]=(sp->restart_interval&255);
02182         *len=6;
02183         *mem=(void*)sp->out_buffer;
02184     }
02185     sp->out_state++;
02186 }
02187 
02188 static void
02189 OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len)
02190 {
02191     OJPEGState* sp=(OJPEGState*)tif->tif_data;
02192     uint8 m;
02193     assert(OJPEG_BUFFER>=2+8+sp->samples_per_pixel_per_plane*3);
02194     assert(255>=8+sp->samples_per_pixel_per_plane*3);
02195     sp->out_buffer[0]=255;
02196     sp->out_buffer[1]=sp->sof_marker_id;
02197     /* Lf */
02198     sp->out_buffer[2]=0;
02199     sp->out_buffer[3]=8+sp->samples_per_pixel_per_plane*3;
02200     /* P */
02201     sp->out_buffer[4]=8;
02202     /* Y */
02203     sp->out_buffer[5]=(sp->sof_y>>8);
02204     sp->out_buffer[6]=(sp->sof_y&255);
02205     /* X */
02206     sp->out_buffer[7]=(sp->sof_x>>8);
02207     sp->out_buffer[8]=(sp->sof_x&255);
02208     /* Nf */
02209     sp->out_buffer[9]=sp->samples_per_pixel_per_plane;
02210     for (m=0; m<sp->samples_per_pixel_per_plane; m++)
02211     {
02212         /* C */
02213         sp->out_buffer[10+m*3]=sp->sof_c[sp->plane_sample_offset+m];
02214         /* H and V */
02215         sp->out_buffer[10+m*3+1]=sp->sof_hv[sp->plane_sample_offset+m];
02216         /* Tq */
02217         sp->out_buffer[10+m*3+2]=sp->sof_tq[sp->plane_sample_offset+m];
02218     }
02219     *len=10+sp->samples_per_pixel_per_plane*3;
02220     *mem=(void*)sp->out_buffer;
02221     sp->out_state++;
02222 }
02223 
02224 static void
02225 OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len)
02226 {
02227     OJPEGState* sp=(OJPEGState*)tif->tif_data;
02228     uint8 m;
02229     assert(OJPEG_BUFFER>=2+6+sp->samples_per_pixel_per_plane*2);
02230     assert(255>=6+sp->samples_per_pixel_per_plane*2);
02231     sp->out_buffer[0]=255;
02232     sp->out_buffer[1]=JPEG_MARKER_SOS;
02233     /* Ls */
02234     sp->out_buffer[2]=0;
02235     sp->out_buffer[3]=6+sp->samples_per_pixel_per_plane*2;
02236     /* Ns */
02237     sp->out_buffer[4]=sp->samples_per_pixel_per_plane;
02238     for (m=0; m<sp->samples_per_pixel_per_plane; m++)
02239     {
02240         /* Cs */
02241         sp->out_buffer[5+m*2]=sp->sos_cs[sp->plane_sample_offset+m];
02242         /* Td and Ta */
02243         sp->out_buffer[5+m*2+1]=sp->sos_tda[sp->plane_sample_offset+m];
02244     }
02245     /* Ss */
02246     sp->out_buffer[5+sp->samples_per_pixel_per_plane*2]=0;
02247     /* Se */
02248     sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+1]=63;
02249     /* Ah and Al */
02250     sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+2]=0;
02251     *len=8+sp->samples_per_pixel_per_plane*2;
02252     *mem=(void*)sp->out_buffer;
02253     sp->out_state++;
02254 }
02255 
02256 static int
02257 OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len)
02258 {
02259     OJPEGState* sp=(OJPEGState*)tif->tif_data;
02260     if (sp->in_buffer_togo==0)
02261     {
02262         if (OJPEGReadBufferFill(sp)==0)
02263             return(0);
02264         assert(sp->in_buffer_togo>0);
02265     }
02266     *len=sp->in_buffer_togo;
02267     *mem=(void*)sp->in_buffer_cur;
02268     sp->in_buffer_togo=0;
02269     if (sp->in_buffer_file_togo==0)
02270     {
02271         switch(sp->in_buffer_source)
02272         {
02273             case osibsStrile:
02274                 if (sp->in_buffer_next_strile<sp->in_buffer_strile_count)  
02275                     sp->out_state=ososRst;
02276                 else
02277                     sp->out_state=ososEoi;
02278                 break;
02279             case osibsEof:
02280                 sp->out_state=ososEoi;
02281                 break;
02282             default:
02283                 break;
02284         }
02285     }
02286     return(1);
02287 }
02288 
02289 static void
02290 OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len)
02291 {
02292     OJPEGState* sp=(OJPEGState*)tif->tif_data;
02293     assert(OJPEG_BUFFER>=2);
02294     sp->out_buffer[0]=255;
02295     sp->out_buffer[1]=JPEG_MARKER_RST0+sp->restart_index;
02296     sp->restart_index++;
02297     if (sp->restart_index==8)
02298         sp->restart_index=0;
02299     *len=2;
02300     *mem=(void*)sp->out_buffer;
02301     sp->out_state=ososCompressed;
02302 }
02303 
02304 static void
02305 OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len)
02306 {
02307     OJPEGState* sp=(OJPEGState*)tif->tif_data;
02308     assert(OJPEG_BUFFER>=2);
02309     sp->out_buffer[0]=255;
02310     sp->out_buffer[1]=JPEG_MARKER_EOI;
02311     *len=2;
02312     *mem=(void*)sp->out_buffer;
02313 }
02314 
02315 #ifndef LIBJPEG_ENCAP_EXTERNAL
02316 static int
02317 jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
02318 {
02319     return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_create_decompress(cinfo),1));
02320 }
02321 #endif
02322 
02323 #ifndef LIBJPEG_ENCAP_EXTERNAL
02324 static int
02325 jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image)
02326 {
02327     return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_header(cinfo,require_image),1));
02328 }
02329 #endif
02330 
02331 #ifndef LIBJPEG_ENCAP_EXTERNAL
02332 static int
02333 jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
02334 {
02335     return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_start_decompress(cinfo),1));
02336 }
02337 #endif
02338 
02339 #ifndef LIBJPEG_ENCAP_EXTERNAL
02340 static int
02341 jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines)
02342 {
02343     return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_scanlines(cinfo,scanlines,max_lines),1));
02344 }
02345 #endif
02346 
02347 #ifndef LIBJPEG_ENCAP_EXTERNAL
02348 static int
02349 jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines)
02350 {
02351     return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_raw_data(cinfo,data,max_lines),1));
02352 }
02353 #endif
02354 
02355 #ifndef LIBJPEG_ENCAP_EXTERNAL
02356 static void
02357 jpeg_encap_unwind(TIFF* tif)
02358 {
02359     OJPEGState* sp=(OJPEGState*)tif->tif_data;
02360     LONGJMP(sp->exit_jmpbuf,1);
02361 }
02362 #endif
02363 
02364 static void
02365 OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo)
02366 {
02367     char buffer[JMSG_LENGTH_MAX];
02368     (*cinfo->err->format_message)(cinfo,buffer);
02369     TIFFWarningExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg", "%s", buffer);
02370 }
02371 
02372 static void
02373 OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo)
02374 {
02375     char buffer[JMSG_LENGTH_MAX];
02376     (*cinfo->err->format_message)(cinfo,buffer);
02377     TIFFErrorExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg", "%s", buffer);
02378     jpeg_encap_unwind((TIFF*)(cinfo->client_data));
02379 }
02380 
02381 static void
02382 OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo)
02383 {
02384     (void)cinfo;
02385 }
02386 
02387 static boolean
02388 OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo)
02389 {
02390     TIFF* tif=(TIFF*)cinfo->client_data;
02391     OJPEGState* sp=(OJPEGState*)tif->tif_data;
02392     void* mem=0;
02393     uint32 len=0;
02394     if (OJPEGWriteStream(tif,&mem,&len)==0)
02395     {
02396         TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Premature end of JPEG data");
02397         jpeg_encap_unwind(tif);
02398     }
02399     sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=len;
02400     sp->libjpeg_jpeg_source_mgr.next_input_byte=mem;
02401     return(1);
02402 }
02403 
02404 static void
02405 OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes)
02406 {
02407     TIFF* tif=(TIFF*)cinfo->client_data;
02408     (void)num_bytes;
02409     TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error");
02410     jpeg_encap_unwind(tif);
02411 }
02412 
02413 static boolean
02414 OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired)
02415 {
02416     TIFF* tif=(TIFF*)cinfo->client_data;
02417     (void)desired;
02418     TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error");
02419     jpeg_encap_unwind(tif);
02420     return(0);
02421 }
02422 
02423 static void
02424 OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo)
02425 {
02426     (void)cinfo;
02427 }
02428 
02429 #endif
02430 
02431 
02432 /*
02433  * Local Variables:
02434  * mode: c
02435  * c-basic-offset: 8
02436  * fill-column: 78
02437  * End:
02438  */

Generated on Fri May 25 2012 04:17:43 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.