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: 2012-12-26 Functions: 12 12 100.0 %

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

Generated by: LCOV version 1.7