Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentif_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
1.7.6.1
|