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_zip.c
Go to the documentation of this file.
00001 /* $Id: tif_zip.c,v 1.11.2.4 2010-06-08 18:50:43 bfriesen Exp $ */
00002 
00003 /*
00004  * Copyright (c) 1995-1997 Sam Leffler
00005  * Copyright (c) 1995-1997 Silicon Graphics, Inc.
00006  *
00007  * Permission to use, copy, modify, distribute, and sell this software and 
00008  * its documentation for any purpose is hereby granted without fee, provided
00009  * that (i) the above copyright notices and this permission notice appear in
00010  * all copies of the software and related documentation, and (ii) the names of
00011  * Sam Leffler and Silicon Graphics may not be used in any advertising or
00012  * publicity relating to the software without the specific, prior written
00013  * permission of Sam Leffler and Silicon Graphics.
00014  * 
00015  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
00016  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
00017  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
00018  * 
00019  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
00020  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
00021  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00022  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
00023  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
00024  * OF THIS SOFTWARE.
00025  */
00026 
00027 #include "tiffiop.h"
00028 #ifdef ZIP_SUPPORT
00029 /*
00030  * TIFF Library.
00031  *
00032  * ZIP (aka Deflate) Compression Support
00033  *
00034  * This file is simply an interface to the zlib library written by
00035  * Jean-loup Gailly and Mark Adler.  You must use version 1.0 or later
00036  * of the library: this code assumes the 1.0 API and also depends on
00037  * the ability to write the zlib header multiple times (one per strip)
00038  * which was not possible with versions prior to 0.95.  Note also that
00039  * older versions of this codec avoided this bug by supressing the header
00040  * entirely.  This means that files written with the old library cannot
00041  * be read; they should be converted to a different compression scheme
00042  * and then reconverted.
00043  *
00044  * The data format used by the zlib library is described in the files
00045  * zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available in the
00046  * directory ftp://ftp.uu.net/pub/archiving/zip/doc.  The library was
00047  * last found at ftp://ftp.uu.net/pub/archiving/zip/zlib/zlib-0.99.tar.gz.
00048  */
00049 #include "tif_predict.h"
00050 #include "zlib.h"
00051 
00052 #include <stdio.h>
00053 
00054 /*
00055  * Sigh, ZLIB_VERSION is defined as a string so there's no
00056  * way to do a proper check here.  Instead we guess based
00057  * on the presence of #defines that were added between the
00058  * 0.95 and 1.0 distributions.
00059  */
00060 #if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED)
00061 #error "Antiquated ZLIB software; you must use version 1.0 or later"
00062 #endif
00063 
00064 /*
00065  * State block for each open TIFF
00066  * file using ZIP compression/decompression.
00067  */
00068 typedef struct {
00069     TIFFPredictorState predict;
00070     z_stream    stream;
00071     int     zipquality;     /* compression level */
00072     int     state;          /* state flags */
00073 #define ZSTATE_INIT_DECODE 0x01
00074 #define ZSTATE_INIT_ENCODE 0x02
00075 
00076     TIFFVGetMethod  vgetparent;     /* super-class method */
00077     TIFFVSetMethod  vsetparent;     /* super-class method */
00078 } ZIPState;
00079 
00080 #define ZState(tif)     ((ZIPState*) (tif)->tif_data)
00081 #define DecoderState(tif)   ZState(tif)
00082 #define EncoderState(tif)   ZState(tif)
00083 
00084 static  int ZIPEncode(TIFF*, tidata_t, tsize_t, tsample_t);
00085 static  int ZIPDecode(TIFF*, tidata_t, tsize_t, tsample_t);
00086 
00087 static int
00088 ZIPSetupDecode(TIFF* tif)
00089 {
00090     ZIPState* sp = DecoderState(tif);
00091     static const char module[] = "ZIPSetupDecode";
00092 
00093     assert(sp != NULL);
00094         
00095         /* if we were last encoding, terminate this mode */
00096     if (sp->state & ZSTATE_INIT_ENCODE) {
00097             deflateEnd(&sp->stream);
00098             sp->state = 0;
00099         }
00100 
00101     if (inflateInit(&sp->stream) != Z_OK) {
00102         TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg);
00103         return (0);
00104     } else {
00105         sp->state |= ZSTATE_INIT_DECODE;
00106         return (1);
00107     }
00108 }
00109 
00110 /*
00111  * Setup state for decoding a strip.
00112  */
00113 static int
00114 ZIPPreDecode(TIFF* tif, tsample_t s)
00115 {
00116     ZIPState* sp = DecoderState(tif);
00117 
00118     (void) s;
00119     assert(sp != NULL);
00120 
00121         if( (sp->state & ZSTATE_INIT_DECODE) == 0 )
00122             tif->tif_setupdecode( tif );
00123 
00124     sp->stream.next_in = tif->tif_rawdata;
00125     sp->stream.avail_in = tif->tif_rawcc;
00126     return (inflateReset(&sp->stream) == Z_OK);
00127 }
00128 
00129 static int
00130 ZIPDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
00131 {
00132     ZIPState* sp = DecoderState(tif);
00133     static const char module[] = "ZIPDecode";
00134 
00135     (void) s;
00136     assert(sp != NULL);
00137         assert(sp->state == ZSTATE_INIT_DECODE);
00138 
00139     sp->stream.next_out = op;
00140     sp->stream.avail_out = occ;
00141     do {
00142         int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
00143         if (state == Z_STREAM_END)
00144             break;
00145         if (state == Z_DATA_ERROR) {
00146             TIFFErrorExt(tif->tif_clientdata, module,
00147                 "%s: Decoding error at scanline %d, %s",
00148                 tif->tif_name, tif->tif_row, sp->stream.msg);
00149             if (inflateSync(&sp->stream) != Z_OK)
00150                 return (0);
00151             continue;
00152         }
00153         if (state != Z_OK) {
00154             TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
00155                 tif->tif_name, sp->stream.msg);
00156             return (0);
00157         }
00158     } while (sp->stream.avail_out > 0);
00159     if (sp->stream.avail_out != 0) {
00160         TIFFErrorExt(tif->tif_clientdata, module,
00161             "%s: Not enough data at scanline %d (short %d bytes)",
00162             tif->tif_name, tif->tif_row, sp->stream.avail_out);
00163         return (0);
00164     }
00165     return (1);
00166 }
00167 
00168 static int
00169 ZIPSetupEncode(TIFF* tif)
00170 {
00171     ZIPState* sp = EncoderState(tif);
00172     static const char module[] = "ZIPSetupEncode";
00173 
00174     assert(sp != NULL);
00175     if (sp->state & ZSTATE_INIT_DECODE) {
00176             inflateEnd(&sp->stream);
00177             sp->state = 0;
00178         }
00179 
00180     if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) {
00181         TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg);
00182         return (0);
00183     } else {
00184         sp->state |= ZSTATE_INIT_ENCODE;
00185         return (1);
00186     }
00187 }
00188 
00189 /*
00190  * Reset encoding state at the start of a strip.
00191  */
00192 static int
00193 ZIPPreEncode(TIFF* tif, tsample_t s)
00194 {
00195     ZIPState *sp = EncoderState(tif);
00196 
00197     (void) s;
00198     assert(sp != NULL);
00199         if( sp->state != ZSTATE_INIT_ENCODE )
00200             tif->tif_setupencode( tif );
00201 
00202     sp->stream.next_out = tif->tif_rawdata;
00203     sp->stream.avail_out = tif->tif_rawdatasize;
00204     return (deflateReset(&sp->stream) == Z_OK);
00205 }
00206 
00207 /*
00208  * Encode a chunk of pixels.
00209  */
00210 static int
00211 ZIPEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
00212 {
00213     ZIPState *sp = EncoderState(tif);
00214     static const char module[] = "ZIPEncode";
00215 
00216         assert(sp != NULL);
00217         assert(sp->state == ZSTATE_INIT_ENCODE);
00218 
00219     (void) s;
00220     sp->stream.next_in = bp;
00221     sp->stream.avail_in = cc;
00222     do {
00223         if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
00224             TIFFErrorExt(tif->tif_clientdata, module, "%s: Encoder error: %s",
00225                 tif->tif_name, sp->stream.msg);
00226             return (0);
00227         }
00228         if (sp->stream.avail_out == 0) {
00229             tif->tif_rawcc = tif->tif_rawdatasize;
00230             TIFFFlushData1(tif);
00231             sp->stream.next_out = tif->tif_rawdata;
00232             sp->stream.avail_out = tif->tif_rawdatasize;
00233         }
00234     } while (sp->stream.avail_in > 0);
00235     return (1);
00236 }
00237 
00238 /*
00239  * Finish off an encoded strip by flushing the last
00240  * string and tacking on an End Of Information code.
00241  */
00242 static int
00243 ZIPPostEncode(TIFF* tif)
00244 {
00245     ZIPState *sp = EncoderState(tif);
00246     static const char module[] = "ZIPPostEncode";
00247     int state;
00248 
00249     sp->stream.avail_in = 0;
00250     do {
00251         state = deflate(&sp->stream, Z_FINISH);
00252         switch (state) {
00253         case Z_STREAM_END:
00254         case Z_OK:
00255             if ((int)sp->stream.avail_out != (int)tif->tif_rawdatasize)
00256                     {
00257                 tif->tif_rawcc =
00258                 tif->tif_rawdatasize - sp->stream.avail_out;
00259                 TIFFFlushData1(tif);
00260                 sp->stream.next_out = tif->tif_rawdata;
00261                 sp->stream.avail_out = tif->tif_rawdatasize;
00262             }
00263             break;
00264         default:
00265             TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
00266             tif->tif_name, sp->stream.msg);
00267             return (0);
00268         }
00269     } while (state != Z_STREAM_END);
00270     return (1);
00271 }
00272 
00273 static void
00274 ZIPCleanup(TIFF* tif)
00275 {
00276     ZIPState* sp = ZState(tif);
00277 
00278     assert(sp != 0);
00279 
00280     (void)TIFFPredictorCleanup(tif);
00281 
00282     tif->tif_tagmethods.vgetfield = sp->vgetparent;
00283     tif->tif_tagmethods.vsetfield = sp->vsetparent;
00284 
00285     if (sp->state & ZSTATE_INIT_ENCODE) {
00286             deflateEnd(&sp->stream);
00287             sp->state = 0;
00288         } else if( sp->state & ZSTATE_INIT_DECODE) {
00289             inflateEnd(&sp->stream);
00290             sp->state = 0;
00291     }
00292     _TIFFfree(sp);
00293     tif->tif_data = NULL;
00294 
00295     _TIFFSetDefaultCompressionState(tif);
00296 }
00297 
00298 static int
00299 ZIPVSetField(TIFF* tif, ttag_t tag, va_list ap)
00300 {
00301     ZIPState* sp = ZState(tif);
00302     static const char module[] = "ZIPVSetField";
00303 
00304     switch (tag) {
00305     case TIFFTAG_ZIPQUALITY:
00306         sp->zipquality = va_arg(ap, int);
00307         if ( sp->state&ZSTATE_INIT_ENCODE ) {
00308             if (deflateParams(&sp->stream,
00309                 sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) {
00310                 TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
00311                     tif->tif_name, sp->stream.msg);
00312                 return (0);
00313             }
00314         }
00315         return (1);
00316     default:
00317         return (*sp->vsetparent)(tif, tag, ap);
00318     }
00319     /*NOTREACHED*/
00320 }
00321 
00322 static int
00323 ZIPVGetField(TIFF* tif, ttag_t tag, va_list ap)
00324 {
00325     ZIPState* sp = ZState(tif);
00326 
00327     switch (tag) {
00328     case TIFFTAG_ZIPQUALITY:
00329         *va_arg(ap, int*) = sp->zipquality;
00330         break;
00331     default:
00332         return (*sp->vgetparent)(tif, tag, ap);
00333     }
00334     return (1);
00335 }
00336 
00337 static const TIFFFieldInfo zipFieldInfo[] = {
00338     { TIFFTAG_ZIPQUALITY,    0, 0,  TIFF_ANY,   FIELD_PSEUDO,
00339       TRUE, FALSE,  "" },
00340 };
00341 
00342 int
00343 TIFFInitZIP(TIFF* tif, int scheme)
00344 {
00345     static const char module[] = "TIFFInitZIP";
00346     ZIPState* sp;
00347 
00348     assert( (scheme == COMPRESSION_DEFLATE)
00349         || (scheme == COMPRESSION_ADOBE_DEFLATE));
00350 
00351     /*
00352      * Merge codec-specific tag information.
00353      */
00354     if (!_TIFFMergeFieldInfo(tif, zipFieldInfo,
00355                  TIFFArrayCount(zipFieldInfo))) {
00356         TIFFErrorExt(tif->tif_clientdata, module,
00357                  "Merging Deflate codec-specific tags failed");
00358         return 0;
00359     }
00360 
00361     /*
00362      * Allocate state block so tag methods have storage to record values.
00363      */
00364     tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (ZIPState));
00365     if (tif->tif_data == NULL)
00366         goto bad;
00367     sp = ZState(tif);
00368     sp->stream.zalloc = NULL;
00369     sp->stream.zfree = NULL;
00370     sp->stream.opaque = NULL;
00371     sp->stream.data_type = Z_BINARY;
00372 
00373     /*
00374      * Override parent get/set field methods.
00375      */
00376     sp->vgetparent = tif->tif_tagmethods.vgetfield;
00377     tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
00378     sp->vsetparent = tif->tif_tagmethods.vsetfield;
00379     tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */
00380 
00381     /* Default values for codec-specific fields */
00382     sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
00383     sp->state = 0;
00384 
00385     /*
00386      * Install codec methods.
00387      */
00388     tif->tif_setupdecode = ZIPSetupDecode;
00389     tif->tif_predecode = ZIPPreDecode;
00390     tif->tif_decoderow = ZIPDecode;
00391     tif->tif_decodestrip = ZIPDecode;
00392     tif->tif_decodetile = ZIPDecode;
00393     tif->tif_setupencode = ZIPSetupEncode;
00394     tif->tif_preencode = ZIPPreEncode;
00395     tif->tif_postencode = ZIPPostEncode;
00396     tif->tif_encoderow = ZIPEncode;
00397     tif->tif_encodestrip = ZIPEncode;
00398     tif->tif_encodetile = ZIPEncode;
00399     tif->tif_cleanup = ZIPCleanup;
00400     /*
00401      * Setup predictor setup.
00402      */
00403     (void) TIFFPredictorInit(tif);
00404     return (1);
00405 bad:
00406     TIFFErrorExt(tif->tif_clientdata, module,
00407              "No space for ZIP state block");
00408     return (0);
00409 }
00410 #endif /* ZIP_SUPORT */
00411 
00412 /* vim: set ts=8 sts=8 sw=8 noet: */
00413 /*
00414  * Local Variables:
00415  * mode: c
00416  * c-basic-offset: 8
00417  * fill-column: 78
00418  * End:
00419  */

Generated on Fri May 25 2012 04:17:44 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.