"Fossies" - the Fresh Open Source Software Archive

Member "PDFlib-Lite-7.0.5p3/libs/tiff/tif_zip.c" (6 Jun 2012, 10458 Bytes) of package /linux/misc/old/PDFlib-Lite-7.0.5p3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "tif_zip.c" see the Fossies "Dox" file reference documentation.

    1 /* PDFlib GmbH cvsid: $Id: tif_zip.c,v 1.9 2005/12/21 14:12:52 rjs Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1995-1997 Sam Leffler
    5  * Copyright (c) 1995-1997 Silicon Graphics, Inc.
    6  *
    7  * Permission to use, copy, modify, distribute, and sell this software and 
    8  * its documentation for any purpose is hereby granted without fee, provided
    9  * that (i) the above copyright notices and this permission notice appear in
   10  * all copies of the software and related documentation, and (ii) the names of
   11  * Sam Leffler and Silicon Graphics may not be used in any advertising or
   12  * publicity relating to the software without the specific, prior written
   13  * permission of Sam Leffler and Silicon Graphics.
   14  * 
   15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
   16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
   17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
   18  * 
   19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
   20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
   21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
   22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
   23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
   24  * OF THIS SOFTWARE.
   25  */
   26 
   27 #include "tiffiop.h"
   28 #ifdef ZIP_SUPPORT
   29 /*
   30  * TIFF Library.
   31  *
   32  * ZIP (aka Deflate) Compression Support
   33  *
   34  * This file is simply an interface to the zlib library written by
   35  * Jean-loup Gailly and Mark Adler.  You must use version 1.0 or later
   36  * of the library: this code assumes the 1.0 API and also depends on
   37  * the ability to write the zlib header multiple times (one per strip)
   38  * which was not possible with versions prior to 0.95.  Note also that
   39  * older versions of this codec avoided this bug by supressing the header
   40  * entirely.  This means that files written with the old library cannot
   41  * be read; they should be converted to a different compression scheme
   42  * and then reconverted.
   43  *
   44  * The data format used by the zlib library is described in the files
   45  * zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available in the
   46  * directory ftp://ftp.uu.net/pub/archiving/zip/doc.  The library was
   47  * last found at ftp://ftp.uu.net/pub/archiving/zip/zlib/zlib-0.99.tar.gz.
   48  */
   49 #include "tif_predict.h"
   50 #include "zlib.h"
   51 
   52 #include <stdio.h>
   53 
   54 /*
   55  * Sigh, ZLIB_VERSION is defined as a string so there's no
   56  * way to do a proper check here.  Instead we guess based
   57  * on the presence of #defines that were added between the
   58  * 0.95 and 1.0 distributions.
   59  */
   60 #if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED)
   61 #error "Antiquated ZLIB software; you must use version 1.0 or later"
   62 #endif
   63 
   64 /*
   65  * State block for each open TIFF
   66  * file using ZIP compression/decompression.
   67  */
   68 typedef struct {
   69     TIFFPredictorState predict;
   70     z_stream    stream;
   71     int     zipquality;     /* compression level */
   72     int     state;          /* state flags */
   73 #define ZSTATE_INIT 0x1     /* zlib setup successfully */
   74 
   75     TIFFVGetMethod  vgetparent;     /* super-class method */
   76     TIFFVSetMethod  vsetparent;     /* super-class method */
   77 } ZIPState;
   78 
   79 #define ZState(tif)     ((ZIPState*) (tif)->tif_data)
   80 #define DecoderState(tif)   ZState(tif)
   81 #define EncoderState(tif)   ZState(tif)
   82 
   83 #ifdef PDFLIB_TIFFWRITE_SUPPORT
   84 static  int ZIPEncode(TIFF*, tidata_t, tsize_t, tsample_t);
   85 #endif /* PDFLIB_TIFFWRITE_SUPPORT */
   86 static  int ZIPDecode(TIFF*, tidata_t, tsize_t, tsample_t);
   87 
   88 static int
   89 ZIPSetupDecode(TIFF* tif)
   90 {
   91     ZIPState* sp = DecoderState(tif);
   92     static const char module[] = "ZIPSetupDecode";
   93 
   94     assert(sp != NULL);
   95     if (inflateInit(&sp->stream) != Z_OK) {
   96         _TIFFError(tif,module,"%s: %s", tif->tif_name, sp->stream.msg);
   97         return (0);
   98     } else {
   99         sp->state |= ZSTATE_INIT;
  100         return (1);
  101     }
  102 }
  103 
  104 /*
  105  * Setup state for decoding a strip.
  106  */
  107 static int
  108 ZIPPreDecode(TIFF* tif, tsample_t s)
  109 {
  110     ZIPState* sp = DecoderState(tif);
  111 
  112     (void) s;
  113     assert(sp != NULL);
  114     sp->stream.next_in = tif->tif_rawdata;
  115     sp->stream.avail_in = tif->tif_rawcc;
  116     return (inflateReset(&sp->stream) == Z_OK);
  117 }
  118 
  119 static int
  120 ZIPDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
  121 {
  122     ZIPState* sp = DecoderState(tif);
  123     static const char module[] = "ZIPDecode";
  124 
  125     (void) s;
  126     assert(sp != NULL);
  127     sp->stream.next_out = op;
  128     sp->stream.avail_out = occ;
  129     do {
  130         int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
  131         if (state == Z_STREAM_END)
  132             break;
  133         if (state == Z_DATA_ERROR) {
  134             _TIFFError(tif, module,
  135                 "%s: Decoding error at scanline %d, %s",
  136                 tif->tif_name, tif->tif_row, sp->stream.msg);
  137             if (inflateSync(&sp->stream) != Z_OK)
  138                 return (0);
  139             continue;
  140         }
  141         if (state != Z_OK) {
  142             _TIFFError(tif, module, "%s: zlib error: %s",
  143                 tif->tif_name, sp->stream.msg);
  144             return (0);
  145         }
  146     } while (sp->stream.avail_out > 0);
  147     if (sp->stream.avail_out != 0) {
  148         _TIFFError(tif, module,
  149             "%s: Not enough data at scanline %d (short %d bytes)",
  150             tif->tif_name, tif->tif_row, sp->stream.avail_out);
  151         return (0);
  152     }
  153     return (1);
  154 }
  155 
  156 #ifdef PDFLIB_TIFFWRITE_SUPPORT
  157 static int
  158 ZIPSetupEncode(TIFF* tif)
  159 {
  160     ZIPState* sp = EncoderState(tif);
  161     static const char module[] = "ZIPSetupEncode";
  162 
  163     assert(sp != NULL);
  164     if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) {
  165         _TIFFError(tif,module,"%s: %s", tif->tif_name, sp->stream.msg);
  166         return (0);
  167     } else {
  168         sp->state |= ZSTATE_INIT;
  169         return (1);
  170     }
  171 }
  172 #endif /* PDFLIB_TIFFWRITE_SUPPORT */
  173 
  174 /*
  175  * Reset encoding state at the start of a strip.
  176  */
  177 #ifdef PDFLIB_TIFFWRITE_SUPPORT
  178 static int
  179 ZIPPreEncode(TIFF* tif, tsample_t s)
  180 {
  181     ZIPState *sp = EncoderState(tif);
  182 
  183     (void) s;
  184     assert(sp != NULL);
  185     sp->stream.next_out = tif->tif_rawdata;
  186     sp->stream.avail_out = tif->tif_rawdatasize;
  187     return (deflateReset(&sp->stream) == Z_OK);
  188 }
  189 #endif /* PDFLIB_TIFFWRITE_SUPPORT */
  190 
  191 /*
  192  * Encode a chunk of pixels.
  193  */
  194 #ifdef PDFLIB_TIFFWRITE_SUPPORT
  195 static int
  196 ZIPEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
  197 {
  198     ZIPState *sp = EncoderState(tif);
  199     static const char module[] = "ZIPEncode";
  200 
  201     (void) s;
  202     sp->stream.next_in = bp;
  203     sp->stream.avail_in = cc;
  204     do {
  205         if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
  206             _TIFFError(tif, module, "%s: Encoder error: %s",
  207                 tif->tif_name, sp->stream.msg);
  208             return (0);
  209         }
  210         if (sp->stream.avail_out == 0) {
  211             tif->tif_rawcc = tif->tif_rawdatasize;
  212             TIFFFlushData1(tif);
  213             sp->stream.next_out = tif->tif_rawdata;
  214             sp->stream.avail_out = tif->tif_rawdatasize;
  215         }
  216     } while (sp->stream.avail_in > 0);
  217     return (1);
  218 }
  219 #endif /* PDFLIB_TIFFWRITE_SUPPORT */
  220 
  221 /*
  222  * Finish off an encoded strip by flushing the last
  223  * string and tacking on an End Of Information code.
  224  */
  225 #ifdef PDFLIB_TIFFWRITE_SUPPORT
  226 static int
  227 ZIPPostEncode(TIFF* tif)
  228 {
  229     ZIPState *sp = EncoderState(tif);
  230     static const char module[] = "ZIPPostEncode";
  231     int state;
  232 
  233     sp->stream.avail_in = 0;
  234     do {
  235         state = deflate(&sp->stream, Z_FINISH);
  236         switch (state) {
  237         case Z_STREAM_END:
  238         case Z_OK:
  239             if ((int)sp->stream.avail_out != (int)tif->tif_rawdatasize)
  240                     {
  241                 tif->tif_rawcc =
  242                 tif->tif_rawdatasize - sp->stream.avail_out;
  243                 TIFFFlushData1(tif);
  244                 sp->stream.next_out = tif->tif_rawdata;
  245                 sp->stream.avail_out = tif->tif_rawdatasize;
  246             }
  247             break;
  248         default:
  249             _TIFFError(tif, module, "%s: zlib error: %s",
  250             tif->tif_name, sp->stream.msg);
  251             return (0);
  252         }
  253     } while (state != Z_STREAM_END);
  254     return (1);
  255 }
  256 #endif /* PDFLIB_TIFFWRITE_SUPPORT */
  257 
  258 static void
  259 ZIPCleanup(TIFF* tif)
  260 {
  261     ZIPState* sp = ZState(tif);
  262     if (sp) {
  263         if (sp->state&ZSTATE_INIT) {
  264             /* NB: avoid problems in the library */
  265             if (tif->tif_mode == O_RDONLY)
  266                 inflateEnd(&sp->stream);
  267             else
  268                 deflateEnd(&sp->stream);
  269         }
  270         _TIFFfree(sp);
  271         tif->tif_data = NULL;
  272     }
  273 }
  274 
  275 static int
  276 ZIPVSetField(TIFF* tif, ttag_t tag, va_list ap)
  277 {
  278     ZIPState* sp = ZState(tif);
  279     static const char module[] = "ZIPVSetField";
  280 
  281     switch (tag) {
  282     case TIFFTAG_ZIPQUALITY:
  283         sp->zipquality = va_arg(ap, int);
  284         if (tif->tif_mode != O_RDONLY && (sp->state&ZSTATE_INIT)) {
  285             if (deflateParams(&sp->stream,
  286                 sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) {
  287                 _TIFFError(tif, module, "%s: zlib error: %s",
  288                     tif->tif_name, sp->stream.msg);
  289                 return (0);
  290             }
  291         }
  292         return (1);
  293     default:
  294         return (*sp->vsetparent)(tif, tag, ap);
  295     }
  296     /*NOTREACHED*/
  297 }
  298 
  299 static int
  300 ZIPVGetField(TIFF* tif, ttag_t tag, va_list ap)
  301 {
  302     ZIPState* sp = ZState(tif);
  303 
  304     switch (tag) {
  305     case TIFFTAG_ZIPQUALITY:
  306         *va_arg(ap, int*) = sp->zipquality;
  307         break;
  308     default:
  309         return (*sp->vgetparent)(tif, tag, ap);
  310     }
  311     return (1);
  312 }
  313 
  314 static const TIFFFieldInfo zipFieldInfo[] = {
  315     { TIFFTAG_ZIPQUALITY,    0, 0,  TIFF_ANY,   FIELD_PSEUDO,
  316       TRUE, FALSE,  "" },
  317 };
  318 #define N(a)    (sizeof (a) / sizeof (a[0]))
  319 
  320 int
  321 TIFFInitZIP(TIFF* tif, int scheme)
  322 {
  323     ZIPState* sp;
  324 
  325     assert( (scheme == COMPRESSION_DEFLATE)
  326         || (scheme == COMPRESSION_ADOBE_DEFLATE));
  327 
  328     /*
  329      * Allocate state block so tag methods have storage to record values.
  330      */
  331     tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (ZIPState));
  332     if (tif->tif_data == NULL)
  333         goto bad;
  334     sp = ZState(tif);
  335     sp->stream.zalloc = NULL;
  336     sp->stream.zfree = NULL;
  337     sp->stream.opaque = NULL;
  338     sp->stream.data_type = Z_BINARY;
  339 
  340     /*
  341      * Merge codec-specific tag information and
  342      * override parent get/set field methods.
  343      */
  344     TIFFMergeFieldInfo(tif, zipFieldInfo, N(zipFieldInfo));
  345     sp->vgetparent = tif->tif_tagmethods.vgetfield;
  346     tif->tif_tagmethods.vgetfield = ZIPVGetField;/* hook for codec tags */
  347     sp->vsetparent = tif->tif_tagmethods.vsetfield;
  348     tif->tif_tagmethods.vsetfield = ZIPVSetField;/* hook for codec tags */
  349 
  350     /* Default values for codec-specific fields */
  351     sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
  352     sp->state = 0;
  353 
  354     /*
  355      * Install codec methods.
  356      */
  357     tif->tif_setupdecode = ZIPSetupDecode;
  358     tif->tif_predecode = ZIPPreDecode;
  359     tif->tif_decoderow = ZIPDecode;
  360     tif->tif_decodestrip = ZIPDecode;
  361     tif->tif_decodetile = ZIPDecode;
  362 #ifdef PDFLIB_TIFFWRITE_SUPPORT
  363     tif->tif_setupencode = ZIPSetupEncode;
  364     tif->tif_preencode = ZIPPreEncode;
  365     tif->tif_postencode = ZIPPostEncode;
  366     tif->tif_encoderow = ZIPEncode;
  367     tif->tif_encodestrip = ZIPEncode;
  368     tif->tif_encodetile = ZIPEncode;
  369 #endif /* PDFLIB_TIFFWRITE_SUPPORT */
  370     tif->tif_cleanup = ZIPCleanup;
  371     /*
  372      * Setup predictor setup.
  373      */
  374     (void) TIFFPredictorInit(tif);
  375     return (1);
  376 bad:
  377     _TIFFError(tif, "TIFFInitZIP", "No space for ZIP state block");
  378     return (0);
  379 }
  380 #endif /* ZIP_SUPORT */
  381 
  382 /* vim: set ts=8 sts=8 sw=8 noet: */