const TIFFField* _TIFFFindOrRegisterField(TIFF *tif, uint32 tag, TIFFDataType dt) { const TIFFField *fld; fld = TIFFFindField(tif, tag, dt); if (fld == NULL) { fld = _TIFFCreateAnonField(tif, tag, dt); if (!_TIFFMergeFields(tif, fld, 1)) return NULL; } return fld; }
void _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray) { if (tif->tif_fields && tif->tif_nfields > 0) { uint32 i; for (i = 0; i < tif->tif_nfields; i++) { TIFFField *fld = tif->tif_fields[i]; if (fld->field_bit == FIELD_CUSTOM && strncmp("Tag ", fld->field_name, 4) == 0) { _TIFFfree(fld->field_name); _TIFFfree(fld); } } _TIFFfree(tif->tif_fields); tif->tif_fields = NULL; tif->tif_nfields = 0; } if (!_TIFFMergeFields(tif, fieldarray->fields, fieldarray->count)) { TIFFErrorExt(tif->tif_clientdata, "_TIFFSetupFields", "Setting up field info failed"); } }
int TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32 n) { static const char module[] = "TIFFMergeFieldInfo"; static const char reason[] = "for fields array"; TIFFField *tp; size_t nfields; uint32 i; if (tif->tif_nfieldscompat > 0) { tif->tif_fieldscompat = (TIFFFieldArray *) _TIFFCheckRealloc(tif, tif->tif_fieldscompat, tif->tif_nfieldscompat + 1, sizeof(TIFFFieldArray), reason); } else { tif->tif_fieldscompat = (TIFFFieldArray *) _TIFFCheckMalloc(tif, 1, sizeof(TIFFFieldArray), reason); } if (!tif->tif_fieldscompat) { TIFFErrorExt(tif->tif_clientdata, module, "Failed to allocate fields array"); return -1; } nfields = tif->tif_nfieldscompat++; tif->tif_fieldscompat[nfields].type = tfiatOther; tif->tif_fieldscompat[nfields].allocated_size = n; tif->tif_fieldscompat[nfields].count = n; tif->tif_fieldscompat[nfields].fields = (TIFFField *)_TIFFCheckMalloc(tif, n, sizeof(TIFFField), reason); if (!tif->tif_fieldscompat[nfields].fields) { TIFFErrorExt(tif->tif_clientdata, module, "Failed to allocate fields array"); return -1; } tp = tif->tif_fieldscompat[nfields].fields; for (i = 0; i < n; i++) { tp->field_tag = info[i].field_tag; tp->field_readcount = info[i].field_readcount; tp->field_writecount = info[i].field_writecount; tp->field_type = info[i].field_type; tp->reserved = 0; tp->set_field_type = _TIFFSetGetType(info[i].field_type, info[i].field_readcount, info[i].field_passcount); tp->get_field_type = _TIFFSetGetType(info[i].field_type, info[i].field_readcount, info[i].field_passcount); tp->field_bit = info[i].field_bit; tp->field_oktochange = info[i].field_oktochange; tp->field_passcount = info[i].field_passcount; tp->field_name = info[i].field_name; tp->field_subfields = NULL; tp++; } if (!_TIFFMergeFields(tif, tif->tif_fieldscompat[nfields].fields, n)) { TIFFErrorExt(tif->tif_clientdata, module, "Setting up field info failed"); return -1; } return 0; }
int TIFFInitLZMA(TIFF* tif, int scheme) { static const char module[] = "TIFFInitLZMA"; LZMAState* sp; lzma_stream tmp_stream = LZMA_STREAM_INIT; assert( scheme == COMPRESSION_LZMA ); /* * Merge codec-specific tag information. */ if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields))) { TIFFErrorExt(tif->tif_clientdata, module, "Merging LZMA2 codec-specific tags failed"); return 0; } /* * Allocate state block so tag methods have storage to record values. */ tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZMAState)); if (tif->tif_data == NULL) goto bad; sp = LState(tif); memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream)); /* * Override parent get/set field methods. */ sp->vgetparent = tif->tif_tagmethods.vgetfield; tif->tif_tagmethods.vgetfield = LZMAVGetField; /* hook for codec tags */ sp->vsetparent = tif->tif_tagmethods.vsetfield; tif->tif_tagmethods.vsetfield = LZMAVSetField; /* hook for codec tags */ /* Default values for codec-specific fields */ sp->preset = LZMA_PRESET_DEFAULT; /* default comp. level */ sp->check = LZMA_CHECK_NONE; sp->state = 0; /* Data filters. So far we are using delta and LZMA2 filters only. */ sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE; /* * The sample size in bytes seems to be reasonable distance for delta * filter. */ sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8) ? 1 : tif->tif_dir.td_bitspersample / 8; sp->filters[0].id = LZMA_FILTER_DELTA; sp->filters[0].options = &sp->opt_delta; lzma_lzma_preset(&sp->opt_lzma, sp->preset); sp->filters[1].id = LZMA_FILTER_LZMA2; sp->filters[1].options = &sp->opt_lzma; sp->filters[2].id = LZMA_VLI_UNKNOWN; sp->filters[2].options = NULL; /* * Install codec methods. */ tif->tif_fixuptags = LZMAFixupTags; tif->tif_setupdecode = LZMASetupDecode; tif->tif_predecode = LZMAPreDecode; tif->tif_decoderow = LZMADecode; tif->tif_decodestrip = LZMADecode; tif->tif_decodetile = LZMADecode; tif->tif_setupencode = LZMASetupEncode; tif->tif_preencode = LZMAPreEncode; tif->tif_postencode = LZMAPostEncode; tif->tif_encoderow = LZMAEncode; tif->tif_encodestrip = LZMAEncode; tif->tif_encodetile = LZMAEncode; tif->tif_cleanup = LZMACleanup; /* * Setup predictor setup. */ (void) TIFFPredictorInit(tif); return 1; bad: TIFFErrorExt(tif->tif_clientdata, module, "No space for LZMA2 state block"); return 0; }
int TIFFInitWebP(TIFF* tif, int scheme) { static const char module[] = "TIFFInitWebP"; WebPState* sp; assert( scheme == COMPRESSION_WEBP ); /* * Merge codec-specific tag information. */ if ( !_TIFFMergeFields(tif, TWebPFields, TIFFArrayCount(TWebPFields)) ) { TIFFErrorExt(tif->tif_clientdata, module, "Merging WebP codec-specific tags failed"); return 0; } /* * Allocate state block so tag methods have storage to record values. */ tif->tif_data = (uint8*) _TIFFmalloc(sizeof(WebPState)); if (tif->tif_data == NULL) goto bad; sp = LState(tif); /* * Override parent get/set field methods. */ sp->vgetparent = tif->tif_tagmethods.vgetfield; tif->tif_tagmethods.vgetfield = TWebPVGetField; /* hook for codec tags */ sp->vsetparent = tif->tif_tagmethods.vsetfield; tif->tif_tagmethods.vsetfield = TWebPVSetField; /* hook for codec tags */ /* Default values for codec-specific fields */ sp->quality_level = 75.0f; /* default comp. level */ sp->lossless = 0; /* default to false */ sp->state = 0; sp->nSamples = 0; sp->psDecoder = NULL; sp->last_y = 0; sp->buffer_offset = 0; sp->pBuffer = NULL; /* * Install codec methods. * Notes: * encoderow is not supported */ tif->tif_fixuptags = TWebPFixupTags; tif->tif_setupdecode = TWebPSetupDecode; tif->tif_predecode = TWebPPreDecode; tif->tif_decoderow = TWebPDecode; tif->tif_decodestrip = TWebPDecode; tif->tif_decodetile = TWebPDecode; tif->tif_setupencode = TWebPSetupEncode; tif->tif_preencode = TWebPPreEncode; tif->tif_postencode = TWebPPostEncode; tif->tif_encoderow = TWebPEncode; tif->tif_encodestrip = TWebPEncode; tif->tif_encodetile = TWebPEncode; tif->tif_cleanup = TWebPCleanup; return 1; bad: TIFFErrorExt(tif->tif_clientdata, module, "No space for WebP state block"); return 0; }
int TIFFInitLERC(TIFF* tif, int scheme) { static const char module[] = "TIFFInitLERC"; LERCState* sp; assert( scheme == COMPRESSION_LERC ); /* * Merge codec-specific tag information. */ if (!_TIFFMergeFields(tif, LERCFields, TIFFArrayCount(LERCFields))) { TIFFErrorExt(tif->tif_clientdata, module, "Merging LERC codec-specific tags failed"); return 0; } /* * Allocate state block so tag methods have storage to record values. */ tif->tif_data = (uint8*) _TIFFcalloc(1, sizeof(LERCState)); if (tif->tif_data == NULL) goto bad; sp = LState(tif); /* * Override parent get/set field methods. */ sp->vgetparent = tif->tif_tagmethods.vgetfield; tif->tif_tagmethods.vgetfield = LERCVGetField; /* hook for codec tags */ sp->vsetparent = tif->tif_tagmethods.vsetfield; tif->tif_tagmethods.vsetfield = LERCVSetField; /* hook for codec tags */ /* * Install codec methods. */ tif->tif_fixuptags = LERCFixupTags; tif->tif_setupdecode = LERCSetupDecode; tif->tif_predecode = LERCPreDecode; tif->tif_decoderow = LERCDecode; tif->tif_decodestrip = LERCDecode; tif->tif_decodetile = LERCDecode; tif->tif_setupencode = LERCSetupEncode; tif->tif_preencode = LERCPreEncode; tif->tif_postencode = LERCPostEncode; tif->tif_encoderow = LERCEncode; tif->tif_encodestrip = LERCEncode; tif->tif_encodetile = LERCEncode; tif->tif_cleanup = LERCCleanup; /* Default values for codec-specific fields */ TIFFSetField(tif, TIFFTAG_LERC_VERSION, LERC_VERSION_2_4); TIFFSetField(tif, TIFFTAG_LERC_ADD_COMPRESSION, LERC_ADD_COMPRESSION_NONE); sp->maxzerror = 0.0; sp->zstd_compress_level = 9; /* default comp. level */ sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */ sp->state = 0; return 1; bad: TIFFErrorExt(tif->tif_clientdata, module, "No space for LERC state block"); return 0; }
int TIFFInitZIP(TIFF* tif, int scheme) { static const char module[] = "TIFFInitZIP"; ZIPState* sp; assert( (scheme == COMPRESSION_DEFLATE) || (scheme == COMPRESSION_ADOBE_DEFLATE)); /* * Merge codec-specific tag information. */ if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) { TIFFErrorExt(tif->tif_clientdata, module, "Merging Deflate codec-specific tags failed"); return 0; } /* * Allocate state block so tag methods have storage to record values. */ tif->tif_data = (uint8*) _TIFFmalloc(sizeof (ZIPState)); if (tif->tif_data == NULL) goto bad; sp = ZState(tif); sp->stream.zalloc = NULL; sp->stream.zfree = NULL; sp->stream.opaque = NULL; sp->stream.data_type = Z_BINARY; /* * Override parent get/set field methods. */ sp->vgetparent = tif->tif_tagmethods.vgetfield; tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */ sp->vsetparent = tif->tif_tagmethods.vsetfield; tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */ /* Default values for codec-specific fields */ sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */ sp->state = 0; /* * Install codec methods. */ tif->tif_fixuptags = ZIPFixupTags; tif->tif_setupdecode = ZIPSetupDecode; tif->tif_predecode = ZIPPreDecode; tif->tif_decoderow = ZIPDecode; tif->tif_decodestrip = ZIPDecode; tif->tif_decodetile = ZIPDecode; tif->tif_setupencode = ZIPSetupEncode; tif->tif_preencode = ZIPPreEncode; tif->tif_postencode = ZIPPostEncode; tif->tif_encoderow = ZIPEncode; tif->tif_encodestrip = ZIPEncode; tif->tif_encodetile = ZIPEncode; tif->tif_cleanup = ZIPCleanup; /* * Setup predictor setup. */ (void) TIFFPredictorInit(tif); return (1); bad: TIFFErrorExt(tif->tif_clientdata, module, "No space for ZIP state block"); return (0); }