📄 tif_predict.c
字号:
/* $Id: tif_predict.c,v 1.11 2006/03/03 14:10:09 dron Exp $ *//* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. * * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. *//* * TIFF Library. * * Predictor Tag Support (used by multiple codecs). */#include "tiffiop.h"#include "tif_predict.h"#define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data)static void horAcc8(TIFF*, tidata_t, tsize_t);static void horAcc16(TIFF*, tidata_t, tsize_t);static void swabHorAcc16(TIFF*, tidata_t, tsize_t);static void horDiff8(TIFF*, tidata_t, tsize_t);static void horDiff16(TIFF*, tidata_t, tsize_t);static void fpAcc(TIFF*, tidata_t, tsize_t);static void fpDiff(TIFF*, tidata_t, tsize_t);static int PredictorDecodeRow(TIFF*, tidata_t, tsize_t, tsample_t);static int PredictorDecodeTile(TIFF*, tidata_t, tsize_t, tsample_t);static int PredictorEncodeRow(TIFF*, tidata_t, tsize_t, tsample_t);static int PredictorEncodeTile(TIFF*, tidata_t, tsize_t, tsample_t);static intPredictorSetup(TIFF* tif){ static const char module[] = "PredictorSetup"; TIFFPredictorState* sp = PredictorState(tif); TIFFDirectory* td = &tif->tif_dir; switch (sp->predictor) /* no differencing */ { case PREDICTOR_NONE: return 1; case PREDICTOR_HORIZONTAL: if (td->td_bitspersample != 8 && td->td_bitspersample != 16) { TIFFErrorExt(tif->tif_clientdata, module, "Horizontal differencing \"Predictor\" not supported with %d-bit samples", td->td_bitspersample); return 0; } break; case PREDICTOR_FLOATINGPOINT: if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) { TIFFErrorExt(tif->tif_clientdata, module, "Floating point \"Predictor\" not supported with %d data format", td->td_sampleformat); return 0; } break; default: TIFFErrorExt(tif->tif_clientdata, module, "\"Predictor\" value %d not supported", sp->predictor); return 0; } sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel : 1); /* * Calculate the scanline/tile-width size in bytes. */ if (isTiled(tif)) sp->rowsize = TIFFTileRowSize(tif); else sp->rowsize = TIFFScanlineSize(tif); return 1;}static intPredictorSetupDecode(TIFF* tif){ TIFFPredictorState* sp = PredictorState(tif); TIFFDirectory* td = &tif->tif_dir; if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif)) return 0; if (sp->predictor == 2) { switch (td->td_bitspersample) { case 8: sp->pfunc = horAcc8; break; case 16: sp->pfunc = horAcc16; break; } /* * Override default decoding method with one that does the * predictor stuff. */ sp->coderow = tif->tif_decoderow; tif->tif_decoderow = PredictorDecodeRow; sp->codestrip = tif->tif_decodestrip; tif->tif_decodestrip = PredictorDecodeTile; sp->codetile = tif->tif_decodetile; tif->tif_decodetile = PredictorDecodeTile; /* * If the data is horizontally differenced 16-bit data that * requires byte-swapping, then it must be byte swapped before * the accumulation step. We do this with a special-purpose * routine and override the normal post decoding logic that * the library setup when the directory was read. */ if (tif->tif_flags & TIFF_SWAB) { if (sp->pfunc == horAcc16) { sp->pfunc = swabHorAcc16; tif->tif_postdecode = _TIFFNoPostDecode; } /* else handle 32-bit case... */ } } else if (sp->predictor == 3) { sp->pfunc = fpAcc; /* * Override default decoding method with one that does the * predictor stuff. */ sp->coderow = tif->tif_decoderow; tif->tif_decoderow = PredictorDecodeRow; sp->codestrip = tif->tif_decodestrip; tif->tif_decodestrip = PredictorDecodeTile; sp->codetile = tif->tif_decodetile; tif->tif_decodetile = PredictorDecodeTile; /* * The data should not be swapped outside of the floating * point predictor, the accumulation routine should return * byres in the native order. */ if (tif->tif_flags & TIFF_SWAB) { tif->tif_postdecode = _TIFFNoPostDecode; } /* * Allocate buffer to keep the decoded bytes before * rearranging in the ight order */ } return 1;}static intPredictorSetupEncode(TIFF* tif){ TIFFPredictorState* sp = PredictorState(tif); TIFFDirectory* td = &tif->tif_dir; if (!(*sp->setupencode)(tif) || !PredictorSetup(tif)) return 0; if (sp->predictor == 2) { switch (td->td_bitspersample) { case 8: sp->pfunc = horDiff8; break; case 16: sp->pfunc = horDiff16; break; } /* * Override default encoding method with one that does the * predictor stuff. */ sp->coderow = tif->tif_encoderow; tif->tif_encoderow = PredictorEncodeRow; sp->codestrip = tif->tif_encodestrip; tif->tif_encodestrip = PredictorEncodeTile; sp->codetile = tif->tif_encodetile; tif->tif_encodetile = PredictorEncodeTile; } else if (sp->predictor == 3) { sp->pfunc = fpDiff; /* * Override default encoding method with one that does the * predictor stuff. */ sp->coderow = tif->tif_encoderow; tif->tif_encoderow = PredictorEncodeRow; sp->codestrip = tif->tif_encodestrip; tif->tif_encodestrip = PredictorEncodeTile; sp->codetile = tif->tif_encodetile; tif->tif_encodetile = PredictorEncodeTile; } return 1;}#define REPEAT4(n, op) \ switch (n) { \ default: { int i; for (i = n-4; i > 0; i--) { op; } } \ case 4: op; \ case 3: op; \ case 2: op; \ case 1: op; \ case 0: ; \ }static voidhorAcc8(TIFF* tif, tidata_t cp0, tsize_t cc){ tsize_t stride = PredictorState(tif)->stride; char* cp = (char*) cp0; if (cc > stride) { cc -= stride; /* * Pipeline the most common cases. */ if (stride == 3) { unsigned int cr = cp[0]; unsigned int cg = cp[1]; unsigned int cb = cp[2]; do { cc -= 3, cp += 3; cp[0] = (char) (cr += cp[0]); cp[1] = (char) (cg += cp[1]); cp[2] = (char) (cb += cp[2]); } while ((int32) cc > 0); } else if (stride == 4) { unsigned int cr = cp[0]; unsigned int cg = cp[1]; unsigned int cb = cp[2]; unsigned int ca = cp[3]; do { cc -= 4, cp += 4; cp[0] = (char) (cr += cp[0]); cp[1] = (char) (cg += cp[1]); cp[2] = (char) (cb += cp[2]); cp[3] = (char) (ca += cp[3]); } while ((int32) cc > 0); } else { do { REPEAT4(stride, cp[stride] = (char) (cp[stride] + *cp); cp++) cc -= stride; } while ((int32) cc > 0); } }}static voidswabHorAcc16(TIFF* tif, tidata_t cp0, tsize_t cc){ tsize_t stride = PredictorState(tif)->stride; uint16* wp = (uint16*) cp0; tsize_t wc = cc / 2; if (wc > stride) { TIFFSwabArrayOfShort(wp, wc); wc -= stride; do { REPEAT4(stride, wp[stride] += wp[0]; wp++) wc -= stride; } while ((int32) wc > 0); }}static voidhorAcc16(TIFF* tif, tidata_t cp0, tsize_t cc){ tsize_t stride = PredictorState(tif)->stride; uint16* wp = (uint16*) cp0; tsize_t wc = cc / 2; if (wc > stride) { wc -= stride; do { REPEAT4(stride, wp[stride] += wp[0]; wp++) wc -= stride; } while ((int32) wc > 0); }}/* * Floating point predictor accumulation routine. */static voidfpAcc(TIFF* tif, tidata_t cp0, tsize_t cc){ tsize_t stride = PredictorState(tif)->stride; uint32 bps = tif->tif_dir.td_bitspersample / 8; tsize_t wc = cc / bps; tsize_t count = cc; uint8 *cp = (uint8 *) cp0; uint8 *tmp = (uint8 *)_TIFFmalloc(cc); if (!tmp) return; while (count > stride) { REPEAT4(stride, cp[stride] += cp[0]; cp++) count -= stride; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -