ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tif_predict.c
Go to the documentation of this file.
00001 /* $Id: tif_predict.c,v 1.11.2.4 2010-06-08 18:50:42 bfriesen Exp $ */
00002 
00003 /*
00004  * Copyright (c) 1988-1997 Sam Leffler
00005  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
00006  *
00007  * Permission to use, copy, modify, distribute, and sell this software and 
00008  * its documentation for any purpose is hereby granted without fee, provided
00009  * that (i) the above copyright notices and this permission notice appear in
00010  * all copies of the software and related documentation, and (ii) the names of
00011  * Sam Leffler and Silicon Graphics may not be used in any advertising or
00012  * publicity relating to the software without the specific, prior written
00013  * permission of Sam Leffler and Silicon Graphics.
00014  * 
00015  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
00016  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
00017  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
00018  * 
00019  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
00020  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
00021  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00022  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
00023  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
00024  * OF THIS SOFTWARE.
00025  */
00026 
00027 /*
00028  * TIFF Library.
00029  *
00030  * Predictor Tag Support (used by multiple codecs).
00031  */
00032 #include "tiffiop.h"
00033 #include "tif_predict.h"
00034 
00035 #define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data)
00036 
00037 static  void horAcc8(TIFF*, tidata_t, tsize_t);
00038 static  void horAcc16(TIFF*, tidata_t, tsize_t);
00039 static  void horAcc32(TIFF*, tidata_t, tsize_t);
00040 static  void swabHorAcc16(TIFF*, tidata_t, tsize_t);
00041 static  void swabHorAcc32(TIFF*, tidata_t, tsize_t);
00042 static  void horDiff8(TIFF*, tidata_t, tsize_t);
00043 static  void horDiff16(TIFF*, tidata_t, tsize_t);
00044 static  void horDiff32(TIFF*, tidata_t, tsize_t);
00045 static  void fpAcc(TIFF*, tidata_t, tsize_t);
00046 static  void fpDiff(TIFF*, tidata_t, tsize_t);
00047 static  int PredictorDecodeRow(TIFF*, tidata_t, tsize_t, tsample_t);
00048 static  int PredictorDecodeTile(TIFF*, tidata_t, tsize_t, tsample_t);
00049 static  int PredictorEncodeRow(TIFF*, tidata_t, tsize_t, tsample_t);
00050 static  int PredictorEncodeTile(TIFF*, tidata_t, tsize_t, tsample_t);
00051 
00052 static int
00053 PredictorSetup(TIFF* tif)
00054 {
00055     static const char module[] = "PredictorSetup";
00056 
00057     TIFFPredictorState* sp = PredictorState(tif);
00058     TIFFDirectory* td = &tif->tif_dir;
00059 
00060     switch (sp->predictor)      /* no differencing */
00061     {
00062         case PREDICTOR_NONE:
00063             return 1;
00064         case PREDICTOR_HORIZONTAL:
00065             if (td->td_bitspersample != 8
00066                 && td->td_bitspersample != 16
00067                 && td->td_bitspersample != 32) {
00068                 TIFFErrorExt(tif->tif_clientdata, module,
00069     "Horizontal differencing \"Predictor\" not supported with %d-bit samples",
00070                       td->td_bitspersample);
00071                 return 0;
00072             }
00073             break;
00074         case PREDICTOR_FLOATINGPOINT:
00075             if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) {
00076                 TIFFErrorExt(tif->tif_clientdata, module,
00077     "Floating point \"Predictor\" not supported with %d data format",
00078                       td->td_sampleformat);
00079                 return 0;
00080             }
00081             break;
00082         default:
00083             TIFFErrorExt(tif->tif_clientdata, module,
00084                   "\"Predictor\" value %d not supported",
00085                   sp->predictor);
00086             return 0;
00087     }
00088     sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
00089         td->td_samplesperpixel : 1);
00090     /*
00091      * Calculate the scanline/tile-width size in bytes.
00092      */
00093     if (isTiled(tif))
00094         sp->rowsize = TIFFTileRowSize(tif);
00095     else
00096         sp->rowsize = TIFFScanlineSize(tif);
00097 
00098     return 1;
00099 }
00100 
00101 static int
00102 PredictorSetupDecode(TIFF* tif)
00103 {
00104     TIFFPredictorState* sp = PredictorState(tif);
00105     TIFFDirectory* td = &tif->tif_dir;
00106 
00107     if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
00108         return 0;
00109 
00110     if (sp->predictor == 2) {
00111         switch (td->td_bitspersample) {
00112             case 8:  sp->decodepfunc = horAcc8; break;
00113             case 16: sp->decodepfunc = horAcc16; break;
00114             case 32: sp->decodepfunc = horAcc32; break;
00115         }
00116         /*
00117          * Override default decoding method with one that does the
00118          * predictor stuff.
00119          */
00120                 if( tif->tif_decoderow != PredictorDecodeRow )
00121                 {
00122                     sp->decoderow = tif->tif_decoderow;
00123                     tif->tif_decoderow = PredictorDecodeRow;
00124                     sp->decodestrip = tif->tif_decodestrip;
00125                     tif->tif_decodestrip = PredictorDecodeTile;
00126                     sp->decodetile = tif->tif_decodetile;
00127                     tif->tif_decodetile = PredictorDecodeTile;
00128                 }
00129         /*
00130          * If the data is horizontally differenced 16-bit data that
00131          * requires byte-swapping, then it must be byte swapped before
00132          * the accumulation step.  We do this with a special-purpose
00133          * routine and override the normal post decoding logic that
00134          * the library setup when the directory was read.
00135          */
00136         if (tif->tif_flags & TIFF_SWAB) {
00137             if (sp->decodepfunc == horAcc16) {
00138                 sp->decodepfunc = swabHorAcc16;
00139                 tif->tif_postdecode = _TIFFNoPostDecode;
00140             } else if (sp->decodepfunc == horAcc32) {
00141                 sp->decodepfunc = swabHorAcc32;
00142                 tif->tif_postdecode = _TIFFNoPostDecode;
00143             }
00144         }
00145     }
00146 
00147     else if (sp->predictor == 3) {
00148         sp->decodepfunc = fpAcc;
00149         /*
00150          * Override default decoding method with one that does the
00151          * predictor stuff.
00152          */
00153                 if( tif->tif_decoderow != PredictorDecodeRow )
00154                 {
00155                     sp->decoderow = tif->tif_decoderow;
00156                     tif->tif_decoderow = PredictorDecodeRow;
00157                     sp->decodestrip = tif->tif_decodestrip;
00158                     tif->tif_decodestrip = PredictorDecodeTile;
00159                     sp->decodetile = tif->tif_decodetile;
00160                     tif->tif_decodetile = PredictorDecodeTile;
00161                 }
00162         /*
00163          * The data should not be swapped outside of the floating
00164          * point predictor, the accumulation routine should return
00165          * byres in the native order.
00166          */
00167         if (tif->tif_flags & TIFF_SWAB) {
00168             tif->tif_postdecode = _TIFFNoPostDecode;
00169         }
00170         /*
00171          * Allocate buffer to keep the decoded bytes before
00172          * rearranging in the ight order
00173          */
00174     }
00175 
00176     return 1;
00177 }
00178 
00179 static int
00180 PredictorSetupEncode(TIFF* tif)
00181 {
00182     TIFFPredictorState* sp = PredictorState(tif);
00183     TIFFDirectory* td = &tif->tif_dir;
00184 
00185     if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
00186         return 0;
00187 
00188     if (sp->predictor == 2) {
00189         switch (td->td_bitspersample) {
00190             case 8:  sp->encodepfunc = horDiff8; break;
00191             case 16: sp->encodepfunc = horDiff16; break;
00192             case 32: sp->encodepfunc = horDiff32; break;
00193         }
00194         /*
00195          * Override default encoding method with one that does the
00196          * predictor stuff.
00197          */
00198                 if( tif->tif_encoderow != PredictorEncodeRow )
00199                 {
00200                     sp->encoderow = tif->tif_encoderow;
00201                     tif->tif_encoderow = PredictorEncodeRow;
00202                     sp->encodestrip = tif->tif_encodestrip;
00203                     tif->tif_encodestrip = PredictorEncodeTile;
00204                     sp->encodetile = tif->tif_encodetile;
00205                     tif->tif_encodetile = PredictorEncodeTile;
00206                 }
00207     }
00208     
00209     else if (sp->predictor == 3) {
00210         sp->encodepfunc = fpDiff;
00211         /*
00212          * Override default encoding method with one that does the
00213          * predictor stuff.
00214          */
00215                 if( tif->tif_encoderow != PredictorEncodeRow )
00216                 {
00217                     sp->encoderow = tif->tif_encoderow;
00218                     tif->tif_encoderow = PredictorEncodeRow;
00219                     sp->encodestrip = tif->tif_encodestrip;
00220                     tif->tif_encodestrip = PredictorEncodeTile;
00221                     sp->encodetile = tif->tif_encodetile;
00222                     tif->tif_encodetile = PredictorEncodeTile;
00223                 }
00224     }
00225 
00226     return 1;
00227 }
00228 
00229 #define REPEAT4(n, op)      \
00230     switch (n) {        \
00231     default: { int i; for (i = n-4; i > 0; i--) { op; } } \
00232     case 4:  op;        \
00233     case 3:  op;        \
00234     case 2:  op;        \
00235     case 1:  op;        \
00236     case 0:  ;          \
00237     }
00238 
00239 static void
00240 horAcc8(TIFF* tif, tidata_t cp0, tsize_t cc)
00241 {
00242     tsize_t stride = PredictorState(tif)->stride;
00243 
00244     char* cp = (char*) cp0;
00245     if (cc > stride) {
00246         cc -= stride;
00247         /*
00248          * Pipeline the most common cases.
00249          */
00250         if (stride == 3)  {
00251             unsigned int cr = cp[0];
00252             unsigned int cg = cp[1];
00253             unsigned int cb = cp[2];
00254             do {
00255                 cc -= 3, cp += 3;
00256                 cp[0] = (char) (cr += cp[0]);
00257                 cp[1] = (char) (cg += cp[1]);
00258                 cp[2] = (char) (cb += cp[2]);
00259             } while ((int32) cc > 0);
00260         } else if (stride == 4)  {
00261             unsigned int cr = cp[0];
00262             unsigned int cg = cp[1];
00263             unsigned int cb = cp[2];
00264             unsigned int ca = cp[3];
00265             do {
00266                 cc -= 4, cp += 4;
00267                 cp[0] = (char) (cr += cp[0]);
00268                 cp[1] = (char) (cg += cp[1]);
00269                 cp[2] = (char) (cb += cp[2]);
00270                 cp[3] = (char) (ca += cp[3]);
00271             } while ((int32) cc > 0);
00272         } else  {
00273             do {
00274                 REPEAT4(stride, cp[stride] =
00275                     (char) (cp[stride] + *cp); cp++)
00276                 cc -= stride;
00277             } while ((int32) cc > 0);
00278         }
00279     }
00280 }
00281 
00282 static void
00283 swabHorAcc16(TIFF* tif, tidata_t cp0, tsize_t cc)
00284 {
00285     tsize_t stride = PredictorState(tif)->stride;
00286     uint16* wp = (uint16*) cp0;
00287     tsize_t wc = cc / 2;
00288 
00289     if (wc > stride) {
00290         TIFFSwabArrayOfShort(wp, wc);
00291         wc -= stride;
00292         do {
00293             REPEAT4(stride, wp[stride] += wp[0]; wp++)
00294             wc -= stride;
00295         } while ((int32) wc > 0);
00296     }
00297 }
00298 
00299 static void
00300 horAcc16(TIFF* tif, tidata_t cp0, tsize_t cc)
00301 {
00302     tsize_t stride = PredictorState(tif)->stride;
00303     uint16* wp = (uint16*) cp0;
00304     tsize_t wc = cc / 2;
00305 
00306     if (wc > stride) {
00307         wc -= stride;
00308         do {
00309             REPEAT4(stride, wp[stride] += wp[0]; wp++)
00310             wc -= stride;
00311         } while ((int32) wc > 0);
00312     }
00313 }
00314 
00315 static void
00316 swabHorAcc32(TIFF* tif, tidata_t cp0, tsize_t cc)
00317 {
00318     tsize_t stride = PredictorState(tif)->stride;
00319     uint32* wp = (uint32*) cp0;
00320     tsize_t wc = cc / 4;
00321 
00322     if (wc > stride) {
00323         TIFFSwabArrayOfLong(wp, wc);
00324         wc -= stride;
00325         do {
00326             REPEAT4(stride, wp[stride] += wp[0]; wp++)
00327             wc -= stride;
00328         } while ((int32) wc > 0);
00329     }
00330 }
00331 
00332 static void
00333 horAcc32(TIFF* tif, tidata_t cp0, tsize_t cc)
00334 {
00335     tsize_t stride = PredictorState(tif)->stride;
00336     uint32* wp = (uint32*) cp0;
00337     tsize_t wc = cc / 4;
00338 
00339     if (wc > stride) {
00340         wc -= stride;
00341         do {
00342             REPEAT4(stride, wp[stride] += wp[0]; wp++)
00343             wc -= stride;
00344         } while ((int32) wc > 0);
00345     }
00346 }
00347 
00348 /*
00349  * Floating point predictor accumulation routine.
00350  */
00351 static void
00352 fpAcc(TIFF* tif, tidata_t cp0, tsize_t cc)
00353 {
00354     tsize_t stride = PredictorState(tif)->stride;
00355     uint32 bps = tif->tif_dir.td_bitspersample / 8;
00356     tsize_t wc = cc / bps;
00357     tsize_t count = cc;
00358     uint8 *cp = (uint8 *) cp0;
00359     uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
00360 
00361     if (!tmp)
00362         return;
00363 
00364     while (count > stride) {
00365         REPEAT4(stride, cp[stride] += cp[0]; cp++)
00366         count -= stride;
00367     }
00368 
00369     _TIFFmemcpy(tmp, cp0, cc);
00370     cp = (uint8 *) cp0;
00371     for (count = 0; count < wc; count++) {
00372         uint32 byte;
00373         for (byte = 0; byte < bps; byte++) {
00374 #if WORDS_BIGENDIAN
00375             cp[bps * count + byte] = tmp[byte * wc + count];
00376 #else
00377             cp[bps * count + byte] =
00378                 tmp[(bps - byte - 1) * wc + count];
00379 #endif
00380         }
00381     }
00382     _TIFFfree(tmp);
00383 }
00384 
00385 /*
00386  * Decode a scanline and apply the predictor routine.
00387  */
00388 static int
00389 PredictorDecodeRow(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
00390 {
00391     TIFFPredictorState *sp = PredictorState(tif);
00392 
00393     assert(sp != NULL);
00394     assert(sp->decoderow != NULL);
00395     assert(sp->decodepfunc != NULL);
00396 
00397     if ((*sp->decoderow)(tif, op0, occ0, s)) {
00398         (*sp->decodepfunc)(tif, op0, occ0);
00399         return 1;
00400     } else
00401         return 0;
00402 }
00403 
00404 /*
00405  * Decode a tile/strip and apply the predictor routine.
00406  * Note that horizontal differencing must be done on a
00407  * row-by-row basis.  The width of a "row" has already
00408  * been calculated at pre-decode time according to the
00409  * strip/tile dimensions.
00410  */
00411 static int
00412 PredictorDecodeTile(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
00413 {
00414     TIFFPredictorState *sp = PredictorState(tif);
00415 
00416     assert(sp != NULL);
00417     assert(sp->decodetile != NULL);
00418 
00419     if ((*sp->decodetile)(tif, op0, occ0, s)) {
00420         tsize_t rowsize = sp->rowsize;
00421         assert(rowsize > 0);
00422         assert(sp->decodepfunc != NULL);
00423         while ((long)occ0 > 0) {
00424             (*sp->decodepfunc)(tif, op0, (tsize_t) rowsize);
00425             occ0 -= rowsize;
00426             op0 += rowsize;
00427         }
00428         return 1;
00429     } else
00430         return 0;
00431 }
00432 
00433 static void
00434 horDiff8(TIFF* tif, tidata_t cp0, tsize_t cc)
00435 {
00436     TIFFPredictorState* sp = PredictorState(tif);
00437     tsize_t stride = sp->stride;
00438     char* cp = (char*) cp0;
00439 
00440     if (cc > stride) {
00441         cc -= stride;
00442         /*
00443          * Pipeline the most common cases.
00444          */
00445         if (stride == 3) {
00446             int r1, g1, b1;
00447             int r2 = cp[0];
00448             int g2 = cp[1];
00449             int b2 = cp[2];
00450             do {
00451                 r1 = cp[3]; cp[3] = r1-r2; r2 = r1;
00452                 g1 = cp[4]; cp[4] = g1-g2; g2 = g1;
00453                 b1 = cp[5]; cp[5] = b1-b2; b2 = b1;
00454                 cp += 3;
00455             } while ((int32)(cc -= 3) > 0);
00456         } else if (stride == 4) {
00457             int r1, g1, b1, a1;
00458             int r2 = cp[0];
00459             int g2 = cp[1];
00460             int b2 = cp[2];
00461             int a2 = cp[3];
00462             do {
00463                 r1 = cp[4]; cp[4] = r1-r2; r2 = r1;
00464                 g1 = cp[5]; cp[5] = g1-g2; g2 = g1;
00465                 b1 = cp[6]; cp[6] = b1-b2; b2 = b1;
00466                 a1 = cp[7]; cp[7] = a1-a2; a2 = a1;
00467                 cp += 4;
00468             } while ((int32)(cc -= 4) > 0);
00469         } else {
00470             cp += cc - 1;
00471             do {
00472                 REPEAT4(stride, cp[stride] -= cp[0]; cp--)
00473             } while ((int32)(cc -= stride) > 0);
00474         }
00475     }
00476 }
00477 
00478 static void
00479 horDiff16(TIFF* tif, tidata_t cp0, tsize_t cc)
00480 {
00481     TIFFPredictorState* sp = PredictorState(tif);
00482     tsize_t stride = sp->stride;
00483     int16 *wp = (int16*) cp0;
00484     tsize_t wc = cc/2;
00485 
00486     if (wc > stride) {
00487         wc -= stride;
00488         wp += wc - 1;
00489         do {
00490             REPEAT4(stride, wp[stride] -= wp[0]; wp--)
00491             wc -= stride;
00492         } while ((int32) wc > 0);
00493     }
00494 }
00495 
00496 static void
00497 horDiff32(TIFF* tif, tidata_t cp0, tsize_t cc)
00498 {
00499     TIFFPredictorState* sp = PredictorState(tif);
00500     tsize_t stride = sp->stride;
00501     int32 *wp = (int32*) cp0;
00502     tsize_t wc = cc/4;
00503 
00504     if (wc > stride) {
00505         wc -= stride;
00506         wp += wc - 1;
00507         do {
00508             REPEAT4(stride, wp[stride] -= wp[0]; wp--)
00509             wc -= stride;
00510         } while ((int32) wc > 0);
00511     }
00512 }
00513 
00514 /*
00515  * Floating point predictor differencing routine.
00516  */
00517 static void
00518 fpDiff(TIFF* tif, tidata_t cp0, tsize_t cc)
00519 {
00520     tsize_t stride = PredictorState(tif)->stride;
00521     uint32 bps = tif->tif_dir.td_bitspersample / 8;
00522     tsize_t wc = cc / bps;
00523     tsize_t count;
00524     uint8 *cp = (uint8 *) cp0;
00525     uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
00526 
00527     if (!tmp)
00528         return;
00529 
00530     _TIFFmemcpy(tmp, cp0, cc);
00531     for (count = 0; count < wc; count++) {
00532         uint32 byte;
00533         for (byte = 0; byte < bps; byte++) {
00534 #if WORDS_BIGENDIAN
00535             cp[byte * wc + count] = tmp[bps * count + byte];
00536 #else
00537             cp[(bps - byte - 1) * wc + count] =
00538                 tmp[bps * count + byte];
00539 #endif
00540         }
00541     }
00542     _TIFFfree(tmp);
00543 
00544     cp = (uint8 *) cp0;
00545     cp += cc - stride - 1;
00546     for (count = cc; count > stride; count -= stride)
00547         REPEAT4(stride, cp[stride] -= cp[0]; cp--)
00548 }
00549 
00550 static int
00551 PredictorEncodeRow(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
00552 {
00553     TIFFPredictorState *sp = PredictorState(tif);
00554 
00555     assert(sp != NULL);
00556     assert(sp->encodepfunc != NULL);
00557     assert(sp->encoderow != NULL);
00558 
00559     /* XXX horizontal differencing alters user's data XXX */
00560     (*sp->encodepfunc)(tif, bp, cc);
00561     return (*sp->encoderow)(tif, bp, cc, s);
00562 }
00563 
00564 static int
00565 PredictorEncodeTile(TIFF* tif, tidata_t bp0, tsize_t cc0, tsample_t s)
00566 {
00567     static const char module[] = "PredictorEncodeTile";
00568     TIFFPredictorState *sp = PredictorState(tif);
00569         uint8 *working_copy;
00570     tsize_t cc = cc0, rowsize;
00571     unsigned char* bp;
00572         int result_code;
00573 
00574     assert(sp != NULL);
00575     assert(sp->encodepfunc != NULL);
00576     assert(sp->encodetile != NULL);
00577 
00578         /* 
00579          * Do predictor manipulation in a working buffer to avoid altering
00580          * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
00581          */
00582         working_copy = (uint8*) _TIFFmalloc(cc0);
00583         if( working_copy == NULL )
00584         {
00585             TIFFErrorExt(tif->tif_clientdata, module, 
00586                          "Out of memory allocating %d byte temp buffer.",
00587                          cc0 );
00588             return 0;
00589         }
00590         memcpy( working_copy, bp0, cc0 );
00591         bp = working_copy;
00592 
00593     rowsize = sp->rowsize;
00594     assert(rowsize > 0);
00595     assert((cc0%rowsize)==0);
00596     while (cc > 0) {
00597         (*sp->encodepfunc)(tif, bp, rowsize);
00598         cc -= rowsize;
00599         bp += rowsize;
00600     }
00601     result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
00602 
00603         _TIFFfree( working_copy );
00604 
00605         return result_code;
00606 }
00607 
00608 #define FIELD_PREDICTOR (FIELD_CODEC+0)     /* XXX */
00609 
00610 static const TIFFFieldInfo predictFieldInfo[] = {
00611     { TIFFTAG_PREDICTOR,     1, 1, TIFF_SHORT,  FIELD_PREDICTOR,
00612       FALSE,    FALSE,  "Predictor" },
00613 };
00614 
00615 static int
00616 PredictorVSetField(TIFF* tif, ttag_t tag, va_list ap)
00617 {
00618     TIFFPredictorState *sp = PredictorState(tif);
00619 
00620     assert(sp != NULL);
00621     assert(sp->vsetparent != NULL);
00622 
00623     switch (tag) {
00624     case TIFFTAG_PREDICTOR:
00625         sp->predictor = (uint16) va_arg(ap, int);
00626         TIFFSetFieldBit(tif, FIELD_PREDICTOR);
00627         break;
00628     default:
00629         return (*sp->vsetparent)(tif, tag, ap);
00630     }
00631     tif->tif_flags |= TIFF_DIRTYDIRECT;
00632     return 1;
00633 }
00634 
00635 static int
00636 PredictorVGetField(TIFF* tif, ttag_t tag, va_list ap)
00637 {
00638     TIFFPredictorState *sp = PredictorState(tif);
00639 
00640     assert(sp != NULL);
00641     assert(sp->vgetparent != NULL);
00642 
00643     switch (tag) {
00644     case TIFFTAG_PREDICTOR:
00645         *va_arg(ap, uint16*) = sp->predictor;
00646         break;
00647     default:
00648         return (*sp->vgetparent)(tif, tag, ap);
00649     }
00650     return 1;
00651 }
00652 
00653 static void
00654 PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
00655 {
00656     TIFFPredictorState* sp = PredictorState(tif);
00657 
00658     (void) flags;
00659     if (TIFFFieldSet(tif,FIELD_PREDICTOR)) {
00660         fprintf(fd, "  Predictor: ");
00661         switch (sp->predictor) {
00662         case 1: fprintf(fd, "none "); break;
00663         case 2: fprintf(fd, "horizontal differencing "); break;
00664         case 3: fprintf(fd, "floating point predictor "); break;
00665         }
00666         fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor);
00667     }
00668     if (sp->printdir)
00669         (*sp->printdir)(tif, fd, flags);
00670 }
00671 
00672 int
00673 TIFFPredictorInit(TIFF* tif)
00674 {
00675     TIFFPredictorState* sp = PredictorState(tif);
00676 
00677     assert(sp != 0);
00678 
00679     /*
00680      * Merge codec-specific tag information.
00681      */
00682     if (!_TIFFMergeFieldInfo(tif, predictFieldInfo,
00683                  TIFFArrayCount(predictFieldInfo))) {
00684         TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit",
00685                  "Merging Predictor codec-specific tags failed");
00686         return 0;
00687     }
00688 
00689     /*
00690      * Override parent get/set field methods.
00691      */
00692     sp->vgetparent = tif->tif_tagmethods.vgetfield;
00693     tif->tif_tagmethods.vgetfield =
00694             PredictorVGetField;/* hook for predictor tag */
00695     sp->vsetparent = tif->tif_tagmethods.vsetfield;
00696     tif->tif_tagmethods.vsetfield =
00697             PredictorVSetField;/* hook for predictor tag */
00698     sp->printdir = tif->tif_tagmethods.printdir;
00699     tif->tif_tagmethods.printdir =
00700             PredictorPrintDir;  /* hook for predictor tag */
00701 
00702     sp->setupdecode = tif->tif_setupdecode;
00703     tif->tif_setupdecode = PredictorSetupDecode;
00704     sp->setupencode = tif->tif_setupencode;
00705     tif->tif_setupencode = PredictorSetupEncode;
00706 
00707     sp->predictor = 1;          /* default value */
00708     sp->encodepfunc = NULL;         /* no predictor routine */
00709     sp->decodepfunc = NULL;         /* no predictor routine */
00710     return 1;
00711 }
00712 
00713 int
00714 TIFFPredictorCleanup(TIFF* tif)
00715 {
00716     TIFFPredictorState* sp = PredictorState(tif);
00717 
00718     assert(sp != 0);
00719 
00720     tif->tif_tagmethods.vgetfield = sp->vgetparent;
00721     tif->tif_tagmethods.vsetfield = sp->vsetparent;
00722     tif->tif_tagmethods.printdir = sp->printdir;
00723     tif->tif_setupdecode = sp->setupdecode;
00724     tif->tif_setupencode = sp->setupencode;
00725 
00726     return 1;
00727 }
00728 
00729 /* vim: set ts=8 sts=8 sw=8 noet: */
00730 /*
00731  * Local Variables:
00732  * mode: c
00733  * c-basic-offset: 8
00734  * fill-column: 78
00735  * End:
00736  */

Generated on Wed May 23 2012 04:17:42 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.