static int PredictorSetup(TIFF* tif) { TIFFPredictorState* sp = PredictorState(tif); TIFFDirectory* td = &tif->tif_dir; if (sp->predictor == 1) /* no differencing */ return (1); if (sp->predictor != 2) { TIFFError(tif->tif_name, "\"Predictor\" value %d not supported", sp->predictor); return (0); } if (td->td_bitspersample != 8 && td->td_bitspersample != 16) { TIFFError(tif->tif_name, "Horizontal differencing \"Predictor\" not supported with %d-bit samples", td->td_bitspersample); 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 int PredictorSetupEncode(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; } return (1); }
static int PredictorSetup(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 && td->td_bitspersample != 32) { 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; } if (td->td_bitspersample != 16 && td->td_bitspersample != 24 && td->td_bitspersample != 32 && td->td_bitspersample != 64) { /* Should 64 be allowed? */ TIFFErrorExt(tif->tif_clientdata, module, "Floating point \"Predictor\" not supported with %d-bit samples", td->td_bitspersample); 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); if (sp->rowsize == 0) return 0; return 1; }
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW static int horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc) { tmsize_t stride = PredictorState(tif)->stride; unsigned char* cp = (unsigned char*) cp0; if((cc%stride)!=0) { TIFFErrorExt(tif->tif_clientdata, "horAcc8", "%s", "(cc%stride)!=0"); return 0; } if (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]; cc -= 3; cp += 3; while (cc>0) { cp[0] = (unsigned char) ((cr += cp[0]) & 0xff); cp[1] = (unsigned char) ((cg += cp[1]) & 0xff); cp[2] = (unsigned char) ((cb += cp[2]) & 0xff); cc -= 3; cp += 3; } } else if (stride == 4) { unsigned int cr = cp[0]; unsigned int cg = cp[1]; unsigned int cb = cp[2]; unsigned int ca = cp[3]; cc -= 4; cp += 4; while (cc>0) { cp[0] = (unsigned char) ((cr += cp[0]) & 0xff); cp[1] = (unsigned char) ((cg += cp[1]) & 0xff); cp[2] = (unsigned char) ((cb += cp[2]) & 0xff); cp[3] = (unsigned char) ((ca += cp[3]) & 0xff); cc -= 4; cp += 4; } } else { cc -= stride; do { REPEAT4(stride, cp[stride] = (unsigned char) ((cp[stride] + *cp) & 0xff); cp++) cc -= stride; } while (cc>0); } } return 1; }
static void horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc) { tmsize_t stride = PredictorState(tif)->stride; char* cp = (char*) cp0; assert((cc%stride)==0); if (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]; cc -= 3; cp += 3; while (cc>0) { cp[0] = (char) (cr += cp[0]); cp[1] = (char) (cg += cp[1]); cp[2] = (char) (cb += cp[2]); cc -= 3; cp += 3; } } else if (stride == 4) { unsigned int cr = cp[0]; unsigned int cg = cp[1]; unsigned int cb = cp[2]; unsigned int ca = cp[3]; cc -= 4; cp += 4; while (cc>0) { cp[0] = (char) (cr += cp[0]); cp[1] = (char) (cg += cp[1]); cp[2] = (char) (cb += cp[2]); cp[3] = (char) (ca += cp[3]); cc -= 4; cp += 4; } } else { cc -= stride; do { REPEAT4(stride, cp[stride] = (char) (cp[stride] + *cp); cp++) cc -= stride; } while (cc>0); } } }
static void horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) { tmsize_t stride = PredictorState(tif)->stride; uint16* wp = (uint16*) cp0; tmsize_t wc = cc / 2; assert((cc%(2*stride))==0); if (wc > stride) { wc -= stride; do { REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] + (unsigned int)wp[0]) & 0xffff); wp++) wc -= stride; } while (wc > 0); }
static void swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) { tmsize_t stride = PredictorState(tif)->stride; uint16* wp = (uint16*) cp0; tmsize_t wc = cc / 2; assert((cc%(2*stride))==0); if (wc > stride) { TIFFSwabArrayOfShort(wp, wc); wc -= stride; do { REPEAT4(stride, wp[stride] += wp[0]; wp++) wc -= stride; } while (wc > 0); }
static int PredictorSetupDecode(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... */ } } return (1); }
static void horAcc8(TIFF* tif, tidata_t cp0, tsize_t cc) { TIFFPredictorState* sp = PredictorState(tif); tsize_t stride = sp->stride; char* cp = (char*) cp0; if (cc > stride) { cc -= stride; /* * Pipeline the most common cases. */ if (stride == 3) { u_int cr = cp[0]; u_int cg = cp[1]; u_int cb = cp[2]; do { cc -= 3, cp += 3; cp[0] = (cr += cp[0]); cp[1] = (cg += cp[1]); cp[2] = (cb += cp[2]); } while ((int32) cc > 0); } else if (stride == 4) { u_int cr = cp[0]; u_int cg = cp[1]; u_int cb = cp[2]; u_int ca = cp[3]; do { cc -= 4, cp += 4; cp[0] = (cr += cp[0]); cp[1] = (cg += cp[1]); cp[2] = (cb += cp[2]); cp[3] = (ca += cp[3]); } while ((int32) cc > 0); } else { do { REPEAT4(stride, cp[stride] += *cp; cp++) cc -= stride; } while ((int32) cc > 0); } }
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW static int horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) { tmsize_t stride = PredictorState(tif)->stride; uint16* wp = (uint16*) cp0; tmsize_t wc = cc / 2; if((cc%(2*stride))!=0) { TIFFErrorExt(tif->tif_clientdata, "horAcc16", "%s", "cc%(2*stride))!=0"); return 0; } if (wc > stride) { wc -= stride; do { REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] + (unsigned int)wp[0]) & 0xffff); wp++) wc -= stride; } while (wc > 0); }
static int PredictorSetupDecode(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 int PredictorSetupEncode(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->encodepfunc = horDiff8; break; case 16: sp->encodepfunc = horDiff16; break; case 32: sp->encodepfunc = horDiff32; break; } /* * Override default encoding method with one that does the * predictor stuff. */ if( tif->tif_encoderow != PredictorEncodeRow ) { sp->encoderow = tif->tif_encoderow; tif->tif_encoderow = PredictorEncodeRow; sp->encodestrip = tif->tif_encodestrip; tif->tif_encodestrip = PredictorEncodeTile; sp->encodetile = tif->tif_encodetile; tif->tif_encodetile = PredictorEncodeTile; } /* * If the data is horizontally differenced 16-bit data that * requires byte-swapping, then it must be byte swapped after * the differentiation 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->encodepfunc == horDiff16) { sp->encodepfunc = swabHorDiff16; tif->tif_postdecode = _TIFFNoPostDecode; } else if (sp->encodepfunc == horDiff32) { sp->encodepfunc = swabHorDiff32; tif->tif_postdecode = _TIFFNoPostDecode; } } } else if (sp->predictor == 3) { sp->encodepfunc = fpDiff; /* * Override default encoding method with one that does the * predictor stuff. */ if( tif->tif_encoderow != PredictorEncodeRow ) { sp->encoderow = tif->tif_encoderow; tif->tif_encoderow = PredictorEncodeRow; sp->encodestrip = tif->tif_encodestrip; tif->tif_encodestrip = PredictorEncodeTile; sp->encodetile = tif->tif_encodetile; tif->tif_encodetile = PredictorEncodeTile; } } return 1; }