LCOV - code coverage report
Current view: directory - frmts/gtiff/libtiff - tif_zip.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 176 141 80.1 %
Date: 2013-03-30 Functions: 12 12 100.0 %

       1                 : /* $Id: tif_zip.c,v 1.32 2012-10-18 17:34:59 fwarmerdam 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                 : #define SAFE_MSG(sp)   ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg)
      65                 : 
      66                 : /*
      67                 :  * State block for each open TIFF
      68                 :  * file using ZIP compression/decompression.
      69                 :  */
      70                 : typedef struct {
      71                 :   TIFFPredictorState predict;
      72                 :         z_stream        stream;
      73                 :   int             zipquality;            /* compression level */
      74                 :   int             state;                 /* state flags */
      75                 : #define ZSTATE_INIT_DECODE 0x01
      76                 : #define ZSTATE_INIT_ENCODE 0x02
      77                 : 
      78                 :   TIFFVGetMethod  vgetparent;            /* super-class method */
      79                 :   TIFFVSetMethod  vsetparent;            /* super-class method */
      80                 : } ZIPState;
      81                 : 
      82                 : #define ZState(tif)             ((ZIPState*) (tif)->tif_data)
      83                 : #define DecoderState(tif)       ZState(tif)
      84                 : #define EncoderState(tif)       ZState(tif)
      85                 : 
      86                 : static int ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
      87                 : static int ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s);
      88                 : 
      89                 : static int
      90             492 : ZIPFixupTags(TIFF* tif)
      91                 : {
      92                 :   (void) tif;
      93             492 :   return (1);
      94                 : }
      95                 : 
      96                 : static int
      97             123 : ZIPSetupDecode(TIFF* tif)
      98                 : {
      99                 :   static const char module[] = "ZIPSetupDecode";
     100             123 :   ZIPState* sp = DecoderState(tif);
     101                 : 
     102             123 :   assert(sp != NULL);
     103                 :         
     104                 :         /* if we were last encoding, terminate this mode */
     105             123 :   if (sp->state & ZSTATE_INIT_ENCODE) {
     106               2 :       deflateEnd(&sp->stream);
     107               2 :       sp->state = 0;
     108                 :   }
     109                 : 
     110             123 :   if (inflateInit(&sp->stream) != Z_OK) {
     111               0 :     TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp));
     112               0 :     return (0);
     113                 :   } else {
     114             123 :     sp->state |= ZSTATE_INIT_DECODE;
     115             123 :     return (1);
     116                 :   }
     117                 : }
     118                 : 
     119                 : /*
     120                 :  * Setup state for decoding a strip.
     121                 :  */
     122                 : static int
     123             421 : ZIPPreDecode(TIFF* tif, uint16 s)
     124                 : {
     125                 :   static const char module[] = "ZIPPreDecode";
     126             421 :   ZIPState* sp = DecoderState(tif);
     127                 : 
     128                 :   (void) s;
     129             421 :   assert(sp != NULL);
     130                 : 
     131             421 :   if( (sp->state & ZSTATE_INIT_DECODE) == 0 )
     132               2 :             tif->tif_setupdecode( tif );
     133                 : 
     134             421 :   sp->stream.next_in = tif->tif_rawdata;
     135                 :   assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
     136                 :       we need to simplify this code to reflect a ZLib that is likely updated
     137                 :       to deal with 8byte memory sizes, though this code will respond
     138                 :       apropriately even before we simplify it */
     139             421 :   sp->stream.avail_in = (uInt) tif->tif_rawcc;
     140             421 :   if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
     141                 :   {
     142               0 :     TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
     143               0 :     return (0);
     144                 :   }
     145             421 :   return (inflateReset(&sp->stream) == Z_OK);
     146                 : }
     147                 : 
     148                 : static int
     149             421 : ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
     150                 : {
     151                 :   static const char module[] = "ZIPDecode";
     152             421 :   ZIPState* sp = DecoderState(tif);
     153                 : 
     154                 :   (void) s;
     155             421 :   assert(sp != NULL);
     156             421 :   assert(sp->state == ZSTATE_INIT_DECODE);
     157                 : 
     158             421 :         sp->stream.next_in = tif->tif_rawcp;
     159             421 :   sp->stream.avail_in = (uInt) tif->tif_rawcc;
     160                 :         
     161             421 :   sp->stream.next_out = op;
     162                 :   assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
     163                 :       we need to simplify this code to reflect a ZLib that is likely updated
     164                 :       to deal with 8byte memory sizes, though this code will respond
     165                 :       apropriately even before we simplify it */
     166             421 :   sp->stream.avail_out = (uInt) occ;
     167             421 :   if ((tmsize_t)sp->stream.avail_out != occ)
     168                 :   {
     169               0 :     TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
     170               0 :     return (0);
     171                 :   }
     172                 :   do {
     173             421 :     int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
     174             421 :     if (state == Z_STREAM_END)
     175             369 :       break;
     176              52 :     if (state == Z_DATA_ERROR) {
     177               0 :       TIFFErrorExt(tif->tif_clientdata, module,
     178                 :           "Decoding error at scanline %lu, %s",
     179                 :            (unsigned long) tif->tif_row, SAFE_MSG(sp));
     180               0 :       if (inflateSync(&sp->stream) != Z_OK)
     181               0 :         return (0);
     182               0 :       continue;
     183                 :     }
     184              52 :     if (state != Z_OK) {
     185               0 :       TIFFErrorExt(tif->tif_clientdata, module, 
     186                 :              "ZLib error: %s", SAFE_MSG(sp));
     187               0 :       return (0);
     188                 :     }
     189              52 :   } while (sp->stream.avail_out > 0);
     190             421 :   if (sp->stream.avail_out != 0) {
     191               0 :     TIFFErrorExt(tif->tif_clientdata, module,
     192                 :         "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)",
     193                 :         (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out);
     194               0 :     return (0);
     195                 :   }
     196                 : 
     197             421 :         tif->tif_rawcp = sp->stream.next_in;
     198             421 :         tif->tif_rawcc = sp->stream.avail_in;
     199                 : 
     200             421 :   return (1);
     201                 : }
     202                 : 
     203                 : static int
     204              61 : ZIPSetupEncode(TIFF* tif)
     205                 : {
     206                 :   static const char module[] = "ZIPSetupEncode";
     207              61 :   ZIPState* sp = EncoderState(tif);
     208                 : 
     209              61 :   assert(sp != NULL);
     210              61 :   if (sp->state & ZSTATE_INIT_DECODE) {
     211               4 :     inflateEnd(&sp->stream);
     212               4 :     sp->state = 0;
     213                 :   }
     214                 : 
     215              61 :   if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) {
     216               0 :     TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp));
     217               0 :     return (0);
     218                 :   } else {
     219              61 :     sp->state |= ZSTATE_INIT_ENCODE;
     220              61 :     return (1);
     221                 :   }
     222                 : }
     223                 : 
     224                 : /*
     225                 :  * Reset encoding state at the start of a strip.
     226                 :  */
     227                 : static int
     228             587 : ZIPPreEncode(TIFF* tif, uint16 s)
     229                 : {
     230                 :   static const char module[] = "ZIPPreEncode";
     231             587 :   ZIPState *sp = EncoderState(tif);
     232                 : 
     233                 :   (void) s;
     234             587 :   assert(sp != NULL);
     235             587 :   if( sp->state != ZSTATE_INIT_ENCODE )
     236               4 :             tif->tif_setupencode( tif );
     237                 : 
     238             587 :   sp->stream.next_out = tif->tif_rawdata;
     239                 :   assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
     240                 :       we need to simplify this code to reflect a ZLib that is likely updated
     241                 :       to deal with 8byte memory sizes, though this code will respond
     242                 :       apropriately even before we simplify it */
     243             587 :   sp->stream.avail_out = tif->tif_rawdatasize;
     244             587 :   if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
     245                 :   {
     246               0 :     TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
     247               0 :     return (0);
     248                 :   }
     249             587 :   return (deflateReset(&sp->stream) == Z_OK);
     250                 : }
     251                 : 
     252                 : /*
     253                 :  * Encode a chunk of pixels.
     254                 :  */
     255                 : static int
     256             587 : ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
     257                 : {
     258                 :   static const char module[] = "ZIPEncode";
     259             587 :   ZIPState *sp = EncoderState(tif);
     260                 : 
     261             587 :   assert(sp != NULL);
     262             587 :   assert(sp->state == ZSTATE_INIT_ENCODE);
     263                 : 
     264                 :   (void) s;
     265             587 :   sp->stream.next_in = bp;
     266                 :   assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
     267                 :       we need to simplify this code to reflect a ZLib that is likely updated
     268                 :       to deal with 8byte memory sizes, though this code will respond
     269                 :       apropriately even before we simplify it */
     270             587 :   sp->stream.avail_in = (uInt) cc;
     271             587 :   if ((tmsize_t)sp->stream.avail_in != cc)
     272                 :   {
     273               0 :     TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
     274               0 :     return (0);
     275                 :   }
     276                 :   do {
     277             603 :     if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
     278               0 :       TIFFErrorExt(tif->tif_clientdata, module, 
     279                 :              "Encoder error: %s",
     280                 :              SAFE_MSG(sp));
     281               0 :       return (0);
     282                 :     }
     283             603 :     if (sp->stream.avail_out == 0) {
     284              17 :       tif->tif_rawcc = tif->tif_rawdatasize;
     285              17 :       TIFFFlushData1(tif);
     286              17 :       sp->stream.next_out = tif->tif_rawdata;
     287              17 :       sp->stream.avail_out = (uInt) tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in ZIPPreEncode */
     288                 :     }
     289             603 :   } while (sp->stream.avail_in > 0);
     290             587 :   return (1);
     291                 : }
     292                 : 
     293                 : /*
     294                 :  * Finish off an encoded strip by flushing the last
     295                 :  * string and tacking on an End Of Information code.
     296                 :  */
     297                 : static int
     298             587 : ZIPPostEncode(TIFF* tif)
     299                 : {
     300                 :   static const char module[] = "ZIPPostEncode";
     301             587 :   ZIPState *sp = EncoderState(tif);
     302                 :   int state;
     303                 : 
     304             587 :   sp->stream.avail_in = 0;
     305                 :   do {
     306             597 :     state = deflate(&sp->stream, Z_FINISH);
     307             597 :     switch (state) {
     308                 :     case Z_STREAM_END:
     309                 :     case Z_OK:
     310             597 :       if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
     311                 :       {
     312             597 :         tif->tif_rawcc =  tif->tif_rawdatasize - sp->stream.avail_out;
     313             597 :         TIFFFlushData1(tif);
     314             597 :         sp->stream.next_out = tif->tif_rawdata;
     315             597 :         sp->stream.avail_out = (uInt) tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in ZIPPreEncode */
     316                 :       }
     317                 :       break;
     318                 :     default:
     319               0 :       TIFFErrorExt(tif->tif_clientdata, module, 
     320                 :              "ZLib error: %s", SAFE_MSG(sp));
     321               0 :       return (0);
     322                 :     }
     323             597 :   } while (state != Z_STREAM_END);
     324             587 :   return (1);
     325                 : }
     326                 : 
     327                 : static void
     328             541 : ZIPCleanup(TIFF* tif)
     329                 : {
     330             541 :   ZIPState* sp = ZState(tif);
     331                 : 
     332             541 :   assert(sp != 0);
     333                 : 
     334             541 :   (void)TIFFPredictorCleanup(tif);
     335                 : 
     336             541 :   tif->tif_tagmethods.vgetfield = sp->vgetparent;
     337             541 :   tif->tif_tagmethods.vsetfield = sp->vsetparent;
     338                 : 
     339             541 :   if (sp->state & ZSTATE_INIT_ENCODE) {
     340              59 :     deflateEnd(&sp->stream);
     341              59 :     sp->state = 0;
     342             482 :   } else if( sp->state & ZSTATE_INIT_DECODE) {
     343             119 :     inflateEnd(&sp->stream);
     344             119 :     sp->state = 0;
     345                 :   }
     346             541 :   _TIFFfree(sp);
     347             541 :   tif->tif_data = NULL;
     348                 : 
     349             541 :   _TIFFSetDefaultCompressionState(tif);
     350             541 : }
     351                 : 
     352                 : static int
     353            4754 : ZIPVSetField(TIFF* tif, uint32 tag, va_list ap)
     354                 : {
     355                 :   static const char module[] = "ZIPVSetField";
     356            4754 :   ZIPState* sp = ZState(tif);
     357                 : 
     358            4754 :   switch (tag) {
     359                 :   case TIFFTAG_ZIPQUALITY:
     360               0 :     sp->zipquality = (int) va_arg(ap, int);
     361               0 :     if ( sp->state&ZSTATE_INIT_ENCODE ) {
     362               0 :       if (deflateParams(&sp->stream,
     363                 :           sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) {
     364               0 :         TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
     365                 :                SAFE_MSG(sp));
     366               0 :         return (0);
     367                 :       }
     368                 :     }
     369               0 :     return (1);
     370                 :   default:
     371            4754 :     return (*sp->vsetparent)(tif, tag, ap);
     372                 :   }
     373                 :   /*NOTREACHED*/
     374                 : }
     375                 : 
     376                 : static int
     377            6514 : ZIPVGetField(TIFF* tif, uint32 tag, va_list ap)
     378                 : {
     379            6514 :   ZIPState* sp = ZState(tif);
     380                 : 
     381            6514 :   switch (tag) {
     382                 :   case TIFFTAG_ZIPQUALITY:
     383              10 :     *va_arg(ap, int*) = sp->zipquality;
     384                 :     break;
     385                 :   default:
     386            6504 :     return (*sp->vgetparent)(tif, tag, ap);
     387                 :   }
     388              10 :   return (1);
     389                 : }
     390                 : 
     391                 : static const TIFFField zipFields[] = {
     392                 :     { TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL },
     393                 : };
     394                 : 
     395                 : int
     396             551 : TIFFInitZIP(TIFF* tif, int scheme)
     397                 : {
     398                 :   static const char module[] = "TIFFInitZIP";
     399                 :   ZIPState* sp;
     400                 : 
     401             551 :   assert( (scheme == COMPRESSION_DEFLATE)
     402                 :     || (scheme == COMPRESSION_ADOBE_DEFLATE));
     403                 : 
     404                 :   /*
     405                 :    * Merge codec-specific tag information.
     406                 :    */
     407             551 :   if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) {
     408               0 :     TIFFErrorExt(tif->tif_clientdata, module,
     409                 :            "Merging Deflate codec-specific tags failed");
     410               0 :     return 0;
     411                 :   }
     412                 : 
     413                 :   /*
     414                 :    * Allocate state block so tag methods have storage to record values.
     415                 :    */
     416             551 :   tif->tif_data = (uint8*) _TIFFmalloc(sizeof (ZIPState));
     417             551 :   if (tif->tif_data == NULL)
     418               0 :     goto bad;
     419             551 :   sp = ZState(tif);
     420             551 :   sp->stream.zalloc = NULL;
     421             551 :   sp->stream.zfree = NULL;
     422             551 :   sp->stream.opaque = NULL;
     423             551 :   sp->stream.data_type = Z_BINARY;
     424                 : 
     425                 :   /*
     426                 :    * Override parent get/set field methods.
     427                 :    */
     428             551 :   sp->vgetparent = tif->tif_tagmethods.vgetfield;
     429             551 :   tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
     430             551 :   sp->vsetparent = tif->tif_tagmethods.vsetfield;
     431             551 :   tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */
     432                 : 
     433                 :   /* Default values for codec-specific fields */
     434             551 :   sp->zipquality = Z_DEFAULT_COMPRESSION;  /* default comp. level */
     435             551 :   sp->state = 0;
     436                 : 
     437                 :   /*
     438                 :    * Install codec methods.
     439                 :    */
     440             551 :   tif->tif_fixuptags = ZIPFixupTags; 
     441             551 :   tif->tif_setupdecode = ZIPSetupDecode;
     442             551 :   tif->tif_predecode = ZIPPreDecode;
     443             551 :   tif->tif_decoderow = ZIPDecode;
     444             551 :   tif->tif_decodestrip = ZIPDecode;
     445             551 :   tif->tif_decodetile = ZIPDecode;  
     446             551 :   tif->tif_setupencode = ZIPSetupEncode;
     447             551 :   tif->tif_preencode = ZIPPreEncode;
     448             551 :   tif->tif_postencode = ZIPPostEncode;
     449             551 :   tif->tif_encoderow = ZIPEncode;
     450             551 :   tif->tif_encodestrip = ZIPEncode;
     451             551 :   tif->tif_encodetile = ZIPEncode;
     452             551 :   tif->tif_cleanup = ZIPCleanup;
     453                 :   /*
     454                 :    * Setup predictor setup.
     455                 :    */
     456             551 :   (void) TIFFPredictorInit(tif);
     457             551 :   return (1);
     458                 : bad:
     459               0 :   TIFFErrorExt(tif->tif_clientdata, module,
     460                 :          "No space for ZIP state block");
     461               0 :   return (0);
     462                 : }
     463                 : #endif /* ZIP_SUPORT */
     464                 : 
     465                 : /* vim: set ts=8 sts=8 sw=8 noet: */
     466                 : /*
     467                 :  * Local Variables:
     468                 :  * mode: c
     469                 :  * c-basic-offset: 8
     470                 :  * fill-column: 78
     471                 :  * End:
     472                 :  */

Generated by: LCOV version 1.7