LTP GCOV extension - code coverage report
Current view: directory - frmts/gtiff/libtiff - tif_predict.c
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 373
Code covered: 51.2 % Executed lines: 191

       1                 : /* $Id: tif_predict.c,v 1.32 2010-03-10 18:56:49 bfriesen Exp $ */
       2                 : 
       3                 : /*
       4                 :  * Copyright (c) 1988-1997 Sam Leffler
       5                 :  * Copyright (c) 1991-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                 : /*
      28                 :  * TIFF Library.
      29                 :  *
      30                 :  * Predictor Tag Support (used by multiple codecs).
      31                 :  */
      32                 : #include "tiffiop.h"
      33                 : #include "tif_predict.h"
      34                 : 
      35                 : #define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data)
      36                 : 
      37                 : static void horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc);
      38                 : static void horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
      39                 : static void horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
      40                 : static void swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
      41                 : static void swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
      42                 : static void horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc);
      43                 : static void horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc);
      44                 : static void horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc);
      45                 : static void fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc);
      46                 : static void fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc);
      47                 : static int PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
      48                 : static int PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
      49                 : static int PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
      50                 : static int PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s);
      51                 : 
      52                 : static int
      53                 : PredictorSetup(TIFF* tif)
      54             113 : {
      55                 :   static const char module[] = "PredictorSetup";
      56                 : 
      57             113 :   TIFFPredictorState* sp = PredictorState(tif);
      58             113 :   TIFFDirectory* td = &tif->tif_dir;
      59                 : 
      60             113 :   switch (sp->predictor)   /* no differencing */
      61                 :   {
      62                 :     case PREDICTOR_NONE:
      63              96 :       return 1;
      64                 :     case PREDICTOR_HORIZONTAL:
      65              17 :       if (td->td_bitspersample != 8
      66                 :           && td->td_bitspersample != 16
      67                 :           && td->td_bitspersample != 32) {
      68               0 :         TIFFErrorExt(tif->tif_clientdata, module,
      69                 :             "Horizontal differencing \"Predictor\" not supported with %d-bit samples",
      70                 :             td->td_bitspersample);
      71               0 :         return 0;
      72                 :       }
      73              17 :       break;
      74                 :     case PREDICTOR_FLOATINGPOINT:
      75               0 :       if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) {
      76               0 :         TIFFErrorExt(tif->tif_clientdata, module,
      77                 :             "Floating point \"Predictor\" not supported with %d data format",
      78                 :             td->td_sampleformat);
      79               0 :         return 0;
      80                 :       }
      81               0 :       break;
      82                 :     default:
      83               0 :       TIFFErrorExt(tif->tif_clientdata, module,
      84                 :           "\"Predictor\" value %d not supported",
      85                 :           sp->predictor);
      86               0 :       return 0;
      87                 :   }
      88              17 :   sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
      89                 :       td->td_samplesperpixel : 1);
      90                 :   /*
      91                 :    * Calculate the scanline/tile-width size in bytes.
      92                 :    */
      93              17 :   if (isTiled(tif))
      94              15 :     sp->rowsize = TIFFTileRowSize(tif);
      95                 :   else
      96               2 :     sp->rowsize = TIFFScanlineSize(tif);
      97              17 :   if (sp->rowsize == 0)
      98               0 :     return 0;
      99                 : 
     100              17 :   return 1;
     101                 : }
     102                 : 
     103                 : static int
     104                 : PredictorSetupDecode(TIFF* tif)
     105              76 : {
     106              76 :   TIFFPredictorState* sp = PredictorState(tif);
     107              76 :   TIFFDirectory* td = &tif->tif_dir;
     108                 : 
     109              76 :   if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
     110               0 :     return 0;
     111                 : 
     112              76 :   if (sp->predictor == 2) {
     113               6 :     switch (td->td_bitspersample) {
     114               2 :       case 8:  sp->decodepfunc = horAcc8; break;
     115               4 :       case 16: sp->decodepfunc = horAcc16; break;
     116               0 :       case 32: sp->decodepfunc = horAcc32; break;
     117                 :     }
     118                 :     /*
     119                 :      * Override default decoding method with one that does the
     120                 :      * predictor stuff.
     121                 :      */
     122               6 :                 if( tif->tif_decoderow != PredictorDecodeRow )
     123                 :                 {
     124               6 :                     sp->decoderow = tif->tif_decoderow;
     125               6 :                     tif->tif_decoderow = PredictorDecodeRow;
     126               6 :                     sp->decodestrip = tif->tif_decodestrip;
     127               6 :                     tif->tif_decodestrip = PredictorDecodeTile;
     128               6 :                     sp->decodetile = tif->tif_decodetile;
     129               6 :                     tif->tif_decodetile = PredictorDecodeTile;
     130                 :                 }
     131                 : 
     132                 :     /*
     133                 :      * If the data is horizontally differenced 16-bit data that
     134                 :      * requires byte-swapping, then it must be byte swapped before
     135                 :      * the accumulation step.  We do this with a special-purpose
     136                 :      * routine and override the normal post decoding logic that
     137                 :      * the library setup when the directory was read.
     138                 :      */
     139               6 :     if (tif->tif_flags & TIFF_SWAB) {
     140               1 :       if (sp->decodepfunc == horAcc16) {
     141               1 :         sp->decodepfunc = swabHorAcc16;
     142               1 :         tif->tif_postdecode = _TIFFNoPostDecode;
     143               0 :             } else if (sp->decodepfunc == horAcc32) {
     144               0 :         sp->decodepfunc = swabHorAcc32;
     145               0 :         tif->tif_postdecode = _TIFFNoPostDecode;
     146                 :             }
     147                 :     }
     148                 :   }
     149                 : 
     150              70 :   else if (sp->predictor == 3) {
     151               0 :     sp->decodepfunc = fpAcc;
     152                 :     /*
     153                 :      * Override default decoding method with one that does the
     154                 :      * predictor stuff.
     155                 :      */
     156               0 :                 if( tif->tif_decoderow != PredictorDecodeRow )
     157                 :                 {
     158               0 :                     sp->decoderow = tif->tif_decoderow;
     159               0 :                     tif->tif_decoderow = PredictorDecodeRow;
     160               0 :                     sp->decodestrip = tif->tif_decodestrip;
     161               0 :                     tif->tif_decodestrip = PredictorDecodeTile;
     162               0 :                     sp->decodetile = tif->tif_decodetile;
     163               0 :                     tif->tif_decodetile = PredictorDecodeTile;
     164                 :                 }
     165                 :     /*
     166                 :      * The data should not be swapped outside of the floating
     167                 :      * point predictor, the accumulation routine should return
     168                 :      * byres in the native order.
     169                 :      */
     170               0 :     if (tif->tif_flags & TIFF_SWAB) {
     171               0 :       tif->tif_postdecode = _TIFFNoPostDecode;
     172                 :     }
     173                 :     /*
     174                 :      * Allocate buffer to keep the decoded bytes before
     175                 :      * rearranging in the ight order
     176                 :      */
     177                 :   }
     178                 : 
     179              76 :   return 1;
     180                 : }
     181                 : 
     182                 : static int
     183                 : PredictorSetupEncode(TIFF* tif)
     184              37 : {
     185              37 :   TIFFPredictorState* sp = PredictorState(tif);
     186              37 :   TIFFDirectory* td = &tif->tif_dir;
     187                 : 
     188              37 :   if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
     189               0 :     return 0;
     190                 : 
     191              37 :   if (sp->predictor == 2) {
     192              11 :     switch (td->td_bitspersample) {
     193               3 :       case 8:  sp->encodepfunc = horDiff8; break;
     194               8 :       case 16: sp->encodepfunc = horDiff16; break;
     195               0 :       case 32: sp->encodepfunc = horDiff32; break;
     196                 :     }
     197                 :     /*
     198                 :      * Override default encoding method with one that does the
     199                 :      * predictor stuff.
     200                 :      */
     201              11 :                 if( tif->tif_encoderow != PredictorEncodeRow )
     202                 :                 {
     203              10 :                     sp->encoderow = tif->tif_encoderow;
     204              10 :                     tif->tif_encoderow = PredictorEncodeRow;
     205              10 :                     sp->encodestrip = tif->tif_encodestrip;
     206              10 :                     tif->tif_encodestrip = PredictorEncodeTile;
     207              10 :                     sp->encodetile = tif->tif_encodetile;
     208              10 :                     tif->tif_encodetile = PredictorEncodeTile;
     209                 :                 }
     210                 :   }
     211                 : 
     212              26 :   else if (sp->predictor == 3) {
     213               0 :     sp->encodepfunc = fpDiff;
     214                 :     /*
     215                 :      * Override default encoding method with one that does the
     216                 :      * predictor stuff.
     217                 :      */
     218               0 :                 if( tif->tif_encoderow != PredictorEncodeRow )
     219                 :                 {
     220               0 :                     sp->encoderow = tif->tif_encoderow;
     221               0 :                     tif->tif_encoderow = PredictorEncodeRow;
     222               0 :                     sp->encodestrip = tif->tif_encodestrip;
     223               0 :                     tif->tif_encodestrip = PredictorEncodeTile;
     224               0 :                     sp->encodetile = tif->tif_encodetile;
     225               0 :                     tif->tif_encodetile = PredictorEncodeTile;
     226                 :                 }
     227                 :   }
     228                 : 
     229              37 :   return 1;
     230                 : }
     231                 : 
     232                 : #define REPEAT4(n, op)    \
     233                 :     switch (n) {    \
     234                 :     default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \
     235                 :     case 4:  op;    \
     236                 :     case 3:  op;    \
     237                 :     case 2:  op;    \
     238                 :     case 1:  op;    \
     239                 :     case 0:  ;      \
     240                 :     }
     241                 : 
     242                 : static void
     243                 : horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc)
     244             432 : {
     245             432 :   tmsize_t stride = PredictorState(tif)->stride;
     246                 : 
     247             432 :   char* cp = (char*) cp0;
     248             432 :   assert((cc%stride)==0);
     249             432 :   if (cc > stride) {
     250                 :     /*
     251                 :      * Pipeline the most common cases.
     252                 :      */
     253             432 :     if (stride == 3)  {
     254               0 :       unsigned int cr = cp[0];
     255               0 :       unsigned int cg = cp[1];
     256               0 :       unsigned int cb = cp[2];
     257               0 :       cc -= 3;
     258               0 :       cp += 3;
     259               0 :       while (cc>0) {
     260               0 :         cp[0] = (char) (cr += cp[0]);
     261               0 :         cp[1] = (char) (cg += cp[1]);
     262               0 :         cp[2] = (char) (cb += cp[2]);
     263               0 :         cc -= 3;
     264               0 :         cp += 3;
     265                 :       }
     266             432 :     } else if (stride == 4)  {
     267               0 :       unsigned int cr = cp[0];
     268               0 :       unsigned int cg = cp[1];
     269               0 :       unsigned int cb = cp[2];
     270               0 :       unsigned int ca = cp[3];
     271               0 :       cc -= 4;
     272               0 :       cp += 4;
     273               0 :       while (cc>0) {
     274               0 :         cp[0] = (char) (cr += cp[0]);
     275               0 :         cp[1] = (char) (cg += cp[1]);
     276               0 :         cp[2] = (char) (cb += cp[2]);
     277               0 :         cp[3] = (char) (ca += cp[3]);
     278               0 :         cc -= 4;
     279               0 :         cp += 4;
     280                 :       }
     281                 :     } else  {
     282             432 :       cc -= stride;
     283                 :       do {
     284          102992 :         REPEAT4(stride, cp[stride] =
     285                 :           (char) (cp[stride] + *cp); cp++)
     286          102992 :         cc -= stride;
     287          102992 :       } while (cc>0);
     288                 :     }
     289                 :   }
     290             432 : }
     291                 : 
     292                 : static void
     293                 : swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
     294             122 : {
     295             122 :   tmsize_t stride = PredictorState(tif)->stride;
     296             122 :   uint16* wp = (uint16*) cp0;
     297             122 :   tmsize_t wc = cc / 2;
     298                 : 
     299             122 :   assert((cc%(2*stride))==0);
     300                 : 
     301             122 :   if (wc > stride) {
     302             122 :     TIFFSwabArrayOfShort(wp, wc);
     303             122 :     wc -= stride;
     304                 :     do {
     305           15494 :       REPEAT4(stride, wp[stride] += wp[0]; wp++)
     306           15494 :       wc -= stride;
     307           15494 :     } while (wc > 0);
     308                 :   }
     309             122 : }
     310                 : 
     311                 : static void
     312                 : horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
     313             366 : {
     314             366 :   tmsize_t stride = PredictorState(tif)->stride;
     315             366 :   uint16* wp = (uint16*) cp0;
     316             366 :   tmsize_t wc = cc / 2;
     317                 : 
     318             366 :   assert((cc%(2*stride))==0);
     319                 : 
     320             366 :   if (wc > stride) {
     321             366 :     wc -= stride;
     322                 :     do {
     323           46482 :       REPEAT4(stride, wp[stride] += wp[0]; wp++)
     324           46482 :       wc -= stride;
     325           46482 :     } while (wc > 0);
     326                 :   }
     327             366 : }
     328                 : 
     329                 : static void
     330                 : swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
     331               0 : {
     332               0 :   tmsize_t stride = PredictorState(tif)->stride;
     333               0 :   uint32* wp = (uint32*) cp0;
     334               0 :   tmsize_t wc = cc / 4;
     335                 : 
     336               0 :   assert((cc%(4*stride))==0);
     337                 : 
     338               0 :   if (wc > stride) {
     339               0 :     TIFFSwabArrayOfLong(wp, wc);
     340               0 :     wc -= stride;
     341                 :     do {
     342               0 :       REPEAT4(stride, wp[stride] += wp[0]; wp++)
     343               0 :       wc -= stride;
     344               0 :     } while (wc > 0);
     345                 :   }
     346               0 : }
     347                 : 
     348                 : static void
     349                 : horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
     350               0 : {
     351               0 :   tmsize_t stride = PredictorState(tif)->stride;
     352               0 :   uint32* wp = (uint32*) cp0;
     353               0 :   tmsize_t wc = cc / 4;
     354                 : 
     355               0 :   assert((cc%(4*stride))==0);
     356                 : 
     357               0 :   if (wc > stride) {
     358               0 :     wc -= stride;
     359                 :     do {
     360               0 :       REPEAT4(stride, wp[stride] += wp[0]; wp++)
     361               0 :       wc -= stride;
     362               0 :     } while (wc > 0);
     363                 :   }
     364               0 : }
     365                 : 
     366                 : /*
     367                 :  * Floating point predictor accumulation routine.
     368                 :  */
     369                 : static void
     370                 : fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc)
     371               0 : {
     372               0 :   tmsize_t stride = PredictorState(tif)->stride;
     373               0 :   uint32 bps = tif->tif_dir.td_bitspersample / 8;
     374               0 :   tmsize_t wc = cc / bps;
     375               0 :   tmsize_t count = cc;
     376               0 :   uint8 *cp = (uint8 *) cp0;
     377               0 :   uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
     378                 : 
     379               0 :   assert((cc%(bps*stride))==0);
     380                 : 
     381               0 :   if (!tmp)
     382               0 :     return;
     383                 : 
     384               0 :   while (count > stride) {
     385               0 :     REPEAT4(stride, cp[stride] += cp[0]; cp++)
     386               0 :     count -= stride;
     387                 :   }
     388                 : 
     389               0 :   _TIFFmemcpy(tmp, cp0, cc);
     390               0 :   cp = (uint8 *) cp0;
     391               0 :   for (count = 0; count < wc; count++) {
     392                 :     uint32 byte;
     393               0 :     for (byte = 0; byte < bps; byte++) {
     394                 :       #if WORDS_BIGENDIAN
     395                 :       cp[bps * count + byte] = tmp[byte * wc + count];
     396                 :       #else
     397               0 :       cp[bps * count + byte] =
     398                 :         tmp[(bps - byte - 1) * wc + count];
     399                 :       #endif
     400                 :     }
     401                 :   }
     402               0 :   _TIFFfree(tmp);
     403                 : }
     404                 : 
     405                 : /*
     406                 :  * Decode a scanline and apply the predictor routine.
     407                 :  */
     408                 : static int
     409                 : PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
     410               0 : {
     411               0 :   TIFFPredictorState *sp = PredictorState(tif);
     412                 : 
     413               0 :   assert(sp != NULL);
     414               0 :   assert(sp->decoderow != NULL);
     415               0 :   assert(sp->decodepfunc != NULL);  
     416                 : 
     417               0 :   if ((*sp->decoderow)(tif, op0, occ0, s)) {
     418               0 :     (*sp->decodepfunc)(tif, op0, occ0);
     419               0 :     return 1;
     420                 :   } else
     421               0 :     return 0;
     422                 : }
     423                 : 
     424                 : /*
     425                 :  * Decode a tile/strip and apply the predictor routine.
     426                 :  * Note that horizontal differencing must be done on a
     427                 :  * row-by-row basis.  The width of a "row" has already
     428                 :  * been calculated at pre-decode time according to the
     429                 :  * strip/tile dimensions.
     430                 :  */
     431                 : static int
     432                 : PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
     433               7 : {
     434               7 :   TIFFPredictorState *sp = PredictorState(tif);
     435                 : 
     436               7 :   assert(sp != NULL);
     437               7 :   assert(sp->decodetile != NULL);
     438                 : 
     439               7 :   if ((*sp->decodetile)(tif, op0, occ0, s)) {
     440               7 :     tmsize_t rowsize = sp->rowsize;
     441               7 :     assert(rowsize > 0);
     442               7 :     assert((occ0%rowsize)==0);
     443               7 :     assert(sp->decodepfunc != NULL);
     444             934 :     while (occ0 > 0) {
     445             920 :       (*sp->decodepfunc)(tif, op0, rowsize);
     446             920 :       occ0 -= rowsize;
     447             920 :       op0 += rowsize;
     448                 :     }
     449               7 :     return 1;
     450                 :   } else
     451               0 :     return 0;
     452                 : }
     453                 : 
     454                 : static void
     455                 : horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc)
     456            2080 : {
     457            2080 :   TIFFPredictorState* sp = PredictorState(tif);
     458            2080 :   tmsize_t stride = sp->stride;
     459            2080 :   char* cp = (char*) cp0;
     460                 : 
     461            2080 :   assert((cc%stride)==0);
     462                 : 
     463            2080 :   if (cc > stride) {
     464            2080 :     cc -= stride;
     465                 :     /*
     466                 :      * Pipeline the most common cases.
     467                 :      */
     468            2080 :     if (stride == 3) {
     469                 :       int r1, g1, b1;
     470               0 :       int r2 = cp[0];
     471               0 :       int g2 = cp[1];
     472               0 :       int b2 = cp[2];
     473                 :       do {
     474               0 :         r1 = cp[3]; cp[3] = r1-r2; r2 = r1;
     475               0 :         g1 = cp[4]; cp[4] = g1-g2; g2 = g1;
     476               0 :         b1 = cp[5]; cp[5] = b1-b2; b2 = b1;
     477               0 :         cp += 3;
     478               0 :       } while ((cc -= 3) > 0);
     479            2080 :     } else if (stride == 4) {
     480                 :       int r1, g1, b1, a1;
     481               0 :       int r2 = cp[0];
     482               0 :       int g2 = cp[1];
     483               0 :       int b2 = cp[2];
     484               0 :       int a2 = cp[3];
     485                 :       do {
     486               0 :         r1 = cp[4]; cp[4] = r1-r2; r2 = r1;
     487               0 :         g1 = cp[5]; cp[5] = g1-g2; g2 = g1;
     488               0 :         b1 = cp[6]; cp[6] = b1-b2; b2 = b1;
     489               0 :         a1 = cp[7]; cp[7] = a1-a2; a2 = a1;
     490               0 :         cp += 4;
     491               0 :       } while ((cc -= 4) > 0);
     492                 :     } else {
     493            2080 :       cp += cc - 1;
     494                 :       do {
     495          179168 :         REPEAT4(stride, cp[stride] -= cp[0]; cp--)
     496          179168 :       } while ((cc -= stride) > 0);
     497                 :     }
     498                 :   }
     499            2080 : }
     500                 : 
     501                 : static void
     502                 : horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
     503            1010 : {
     504            1010 :   TIFFPredictorState* sp = PredictorState(tif);
     505            1010 :   tmsize_t stride = sp->stride;
     506            1010 :   int16 *wp = (int16*) cp0;
     507            1010 :   tmsize_t wc = cc/2;
     508                 : 
     509            1010 :   assert((cc%(2*stride))==0);
     510                 : 
     511            1010 :   if (wc > stride) {
     512            1010 :     wc -= stride;
     513            1010 :     wp += wc - 1;
     514                 :     do {
     515          126576 :       REPEAT4(stride, wp[stride] -= wp[0]; wp--)
     516          126576 :       wc -= stride;
     517          126576 :     } while (wc > 0);
     518                 :   }
     519            1010 : }
     520                 : 
     521                 : static void
     522                 : horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
     523               0 : {
     524               0 :   TIFFPredictorState* sp = PredictorState(tif);
     525               0 :   tmsize_t stride = sp->stride;
     526               0 :   int32 *wp = (int32*) cp0;
     527               0 :   tmsize_t wc = cc/4;
     528                 : 
     529               0 :   assert((cc%(4*stride))==0);
     530                 : 
     531               0 :   if (wc > stride) {
     532               0 :     wc -= stride;
     533               0 :     wp += wc - 1;
     534                 :     do {
     535               0 :       REPEAT4(stride, wp[stride] -= wp[0]; wp--)
     536               0 :       wc -= stride;
     537               0 :     } while (wc > 0);
     538                 :   }
     539               0 : }
     540                 : 
     541                 : /*
     542                 :  * Floating point predictor differencing routine.
     543                 :  */
     544                 : static void
     545                 : fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc)
     546               0 : {
     547               0 :   tmsize_t stride = PredictorState(tif)->stride;
     548               0 :   uint32 bps = tif->tif_dir.td_bitspersample / 8;
     549               0 :   tmsize_t wc = cc / bps;
     550                 :   tmsize_t count;
     551               0 :   uint8 *cp = (uint8 *) cp0;
     552               0 :   uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
     553                 : 
     554               0 :   assert((cc%(bps*stride))==0);
     555                 : 
     556               0 :   if (!tmp)
     557               0 :     return;
     558                 : 
     559               0 :   _TIFFmemcpy(tmp, cp0, cc);
     560               0 :   for (count = 0; count < wc; count++) {
     561                 :     uint32 byte;
     562               0 :     for (byte = 0; byte < bps; byte++) {
     563                 :       #if WORDS_BIGENDIAN
     564                 :       cp[byte * wc + count] = tmp[bps * count + byte];
     565                 :       #else
     566               0 :       cp[(bps - byte - 1) * wc + count] =
     567                 :         tmp[bps * count + byte];
     568                 :       #endif
     569                 :     }
     570                 :   }
     571               0 :   _TIFFfree(tmp);
     572                 : 
     573               0 :   cp = (uint8 *) cp0;
     574               0 :   cp += cc - stride - 1;
     575               0 :   for (count = cc; count > stride; count -= stride)
     576               0 :     REPEAT4(stride, cp[stride] -= cp[0]; cp--)
     577                 : }
     578                 : 
     579                 : static int
     580                 : PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
     581               0 : {
     582               0 :   TIFFPredictorState *sp = PredictorState(tif);
     583                 : 
     584               0 :   assert(sp != NULL);
     585               0 :   assert(sp->encodepfunc != NULL);
     586               0 :   assert(sp->encoderow != NULL);
     587                 : 
     588                 :   /* XXX horizontal differencing alters user's data XXX */
     589               0 :   (*sp->encodepfunc)(tif, bp, cc);
     590               0 :   return (*sp->encoderow)(tif, bp, cc, s);
     591                 : }
     592                 : 
     593                 : static int
     594                 : PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s)
     595              65 : {
     596                 :   static const char module[] = "PredictorEncodeTile";
     597              65 :   TIFFPredictorState *sp = PredictorState(tif);
     598                 :         uint8 *working_copy;
     599              65 :   tmsize_t cc = cc0, rowsize;
     600                 :   unsigned char* bp;
     601                 :         int result_code;
     602                 : 
     603              65 :   assert(sp != NULL);
     604              65 :   assert(sp->encodepfunc != NULL);
     605              65 :   assert(sp->encodetile != NULL);
     606                 : 
     607                 :         /* 
     608                 :          * Do predictor manipulation in a working buffer to avoid altering
     609                 :          * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
     610                 :          */
     611              65 :         working_copy = (uint8*) _TIFFmalloc(cc0);
     612              65 :         if( working_copy == NULL )
     613                 :         {
     614               0 :             TIFFErrorExt(tif->tif_clientdata, module, 
     615                 :                          "Out of memory allocating " TIFF_SSIZE_FORMAT " byte temp buffer.",
     616                 :                          cc0 );
     617               0 :             return 0;
     618                 :         }
     619              65 :         memcpy( working_copy, bp0, cc0 );
     620              65 :         bp = working_copy;
     621                 : 
     622              65 :   rowsize = sp->rowsize;
     623              65 :   assert(rowsize > 0);
     624              65 :   assert((cc0%rowsize)==0);
     625            3220 :   while (cc > 0) {
     626            3090 :     (*sp->encodepfunc)(tif, bp, rowsize);
     627            3090 :     cc -= rowsize;
     628            3090 :     bp += rowsize;
     629                 :   }
     630              65 :   result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
     631                 : 
     632              65 :         _TIFFfree( working_copy );
     633                 : 
     634              65 :         return result_code;
     635                 : }
     636                 : 
     637                 : #define FIELD_PREDICTOR (FIELD_CODEC+0)   /* XXX */
     638                 : 
     639                 : static const TIFFField predictFields[] = {
     640                 :     { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL },
     641                 : };
     642                 : 
     643                 : static int
     644                 : PredictorVSetField(TIFF* tif, uint32 tag, va_list ap)
     645            2977 : {
     646            2977 :   TIFFPredictorState *sp = PredictorState(tif);
     647                 : 
     648            2977 :   assert(sp != NULL);
     649            2977 :   assert(sp->vsetparent != NULL);
     650                 : 
     651            2977 :   switch (tag) {
     652                 :   case TIFFTAG_PREDICTOR:
     653             252 :     sp->predictor = (uint16) va_arg(ap, uint16_vap);
     654             252 :     TIFFSetFieldBit(tif, FIELD_PREDICTOR);
     655                 :     break;
     656                 :   default:
     657            2725 :     return (*sp->vsetparent)(tif, tag, ap);
     658                 :   }
     659             252 :   tif->tif_flags |= TIFF_DIRTYDIRECT;
     660             252 :   return 1;
     661                 : }
     662                 : 
     663                 : static int
     664                 : PredictorVGetField(TIFF* tif, uint32 tag, va_list ap)
     665            3927 : {
     666            3927 :   TIFFPredictorState *sp = PredictorState(tif);
     667                 : 
     668            3927 :   assert(sp != NULL);
     669            3927 :   assert(sp->vgetparent != NULL);
     670                 : 
     671            3927 :   switch (tag) {
     672                 :   case TIFFTAG_PREDICTOR:
     673             105 :     *va_arg(ap, uint16*) = sp->predictor;
     674                 :     break;
     675                 :   default:
     676            3822 :     return (*sp->vgetparent)(tif, tag, ap);
     677                 :   }
     678             105 :   return 1;
     679                 : }
     680                 : 
     681                 : static void
     682                 : PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
     683               0 : {
     684               0 :   TIFFPredictorState* sp = PredictorState(tif);
     685                 : 
     686                 :   (void) flags;
     687               0 :   if (TIFFFieldSet(tif,FIELD_PREDICTOR)) {
     688               0 :     fprintf(fd, "  Predictor: ");
     689               0 :     switch (sp->predictor) {
     690               0 :       case 1: fprintf(fd, "none "); break;
     691               0 :       case 2: fprintf(fd, "horizontal differencing "); break;
     692               0 :       case 3: fprintf(fd, "floating point predictor "); break;
     693                 :     }
     694               0 :     fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor);
     695                 :   }
     696               0 :   if (sp->printdir)
     697               0 :     (*sp->printdir)(tif, fd, flags);
     698               0 : }
     699                 : 
     700                 : int
     701                 : TIFFPredictorInit(TIFF* tif)
     702             298 : {
     703             298 :   TIFFPredictorState* sp = PredictorState(tif);
     704                 : 
     705             298 :   assert(sp != 0);
     706                 : 
     707                 :   /*
     708                 :    * Merge codec-specific tag information.
     709                 :    */
     710             298 :   if (!_TIFFMergeFields(tif, predictFields,
     711                 :             TIFFArrayCount(predictFields))) {
     712               0 :     TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit",
     713                 :         "Merging Predictor codec-specific tags failed");
     714               0 :     return 0;
     715                 :   }
     716                 : 
     717                 :   /*
     718                 :    * Override parent get/set field methods.
     719                 :    */
     720             298 :   sp->vgetparent = tif->tif_tagmethods.vgetfield;
     721             298 :   tif->tif_tagmethods.vgetfield =
     722                 :             PredictorVGetField;/* hook for predictor tag */
     723             298 :   sp->vsetparent = tif->tif_tagmethods.vsetfield;
     724             298 :   tif->tif_tagmethods.vsetfield =
     725                 :       PredictorVSetField;/* hook for predictor tag */
     726             298 :   sp->printdir = tif->tif_tagmethods.printdir;
     727             298 :   tif->tif_tagmethods.printdir =
     728                 :             PredictorPrintDir;  /* hook for predictor tag */
     729                 : 
     730             298 :   sp->setupdecode = tif->tif_setupdecode;
     731             298 :   tif->tif_setupdecode = PredictorSetupDecode;
     732             298 :   sp->setupencode = tif->tif_setupencode;
     733             298 :   tif->tif_setupencode = PredictorSetupEncode;
     734                 : 
     735             298 :   sp->predictor = 1;     /* default value */
     736             298 :   sp->encodepfunc = NULL;      /* no predictor routine */
     737             298 :   sp->decodepfunc = NULL;      /* no predictor routine */
     738             298 :   return 1;
     739                 : }
     740                 : 
     741                 : int
     742                 : TIFFPredictorCleanup(TIFF* tif)
     743             288 : {
     744             288 :   TIFFPredictorState* sp = PredictorState(tif);
     745                 : 
     746             288 :   assert(sp != 0);
     747                 : 
     748             288 :   tif->tif_tagmethods.vgetfield = sp->vgetparent;
     749             288 :   tif->tif_tagmethods.vsetfield = sp->vsetparent;
     750             288 :   tif->tif_tagmethods.printdir = sp->printdir;
     751             288 :   tif->tif_setupdecode = sp->setupdecode;
     752             288 :   tif->tif_setupencode = sp->setupencode;
     753                 : 
     754             288 :   return 1;
     755                 : }
     756                 : 
     757                 : /* vim: set ts=8 sts=8 sw=8 noet: */
     758                 : /*
     759                 :  * Local Variables:
     760                 :  * mode: c
     761                 :  * c-basic-offset: 8
     762                 :  * fill-column: 78
     763                 :  * End:
     764                 :  */

Generated by: LTP GCOV extension version 1.5