tif_lzw.c
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C语言 代码 · 共 746 行 · 第 1/2 页
C
746 行
if (code == CODE_EOI)
break;
*op++ = (char)code, occ--;
oldcodep = sp->dec_codetab + code;
continue;
}
codep = sp->dec_codetab + code;
/*
* Add the new entry to the code table.
*/
if (free_entp < &sp->dec_codetab[0] ||
free_entp >= &sp->dec_codetab[CSIZE]) {
TIFFError(tif->tif_name,
"LZWDecode: Corrupted LZW table at scanline %d",
tif->tif_row);
return (0);
}
free_entp->next = oldcodep;
if (free_entp->next < &sp->dec_codetab[0] ||
free_entp->next >= &sp->dec_codetab[CSIZE]) {
TIFFError(tif->tif_name,
"LZWDecode: Corrupted LZW table at scanline %d",
tif->tif_row);
return (0);
}
free_entp->firstchar = free_entp->next->firstchar;
free_entp->length = free_entp->next->length+1;
free_entp->value = (codep < free_entp) ?
codep->firstchar : free_entp->firstchar;
if (++free_entp > maxcodep) {
if (++nbits > BITS_MAX) /* should not happen */
nbits = BITS_MAX;
nbitsmask = MAXCODE(nbits);
maxcodep = sp->dec_codetab + nbitsmask-1;
}
oldcodep = codep;
if (code >= 256) {
/*
* Code maps to a string, copy string
* value to output (written in reverse).
*/
if(codep->length == 0) {
TIFFError(tif->tif_name,
"LZWDecode: Wrong length of decoded string: "
"data probably corrupted at scanline %d",
tif->tif_row);
return (0);
}
if (codep->length > occ) {
/*
* String is too long for decode buffer,
* locate portion that will fit, copy to
* the decode buffer, and setup restart
* logic for the next decoding call.
*/
sp->dec_codep = codep;
do {
codep = codep->next;
} while (codep && codep->length > occ);
if (codep) {
sp->dec_restart = occ;
tp = op + occ;
do {
*--tp = codep->value;
codep = codep->next;
} while (--occ && codep);
if (codep)
codeLoop(tif);
}
break;
}
len = codep->length;
tp = op + len;
do {
int t;
--tp;
t = codep->value;
codep = codep->next;
*tp = (char) t;
} while (codep && tp > op);
if (codep) {
codeLoop(tif);
break;
}
op += len, occ -= len;
} else
*op++ = (char)code, occ--;
}
tif->tif_rawcp = (tidata_t) bp;
sp->lzw_nbits = (u_short) nbits;
sp->lzw_nextdata = nextdata;
sp->lzw_nextbits = nextbits;
sp->dec_nbitsmask = nbitsmask;
sp->dec_oldcodep = oldcodep;
sp->dec_free_entp = free_entp;
sp->dec_maxcodep = maxcodep;
if (occ > 0) {
TIFFError(tif->tif_name,
"LZWDecode: Not enough data at scanline %d (short %d bytes)",
tif->tif_row, occ);
return (0);
}
return (1);
}
#ifdef LZW_COMPAT
/*
* Decode a "hunk of data" for old images.
*/
#define GetNextCodeCompat(sp, bp, code) { \
nextdata |= (u_long) *(bp)++ << nextbits; \
nextbits += 8; \
if (nextbits < nbits) { \
nextdata |= (u_long) *(bp)++ << nextbits; \
nextbits += 8; \
} \
code = (hcode_t)(nextdata & nbitsmask); \
nextdata >>= nbits; \
nextbits -= nbits; \
}
static int
LZWDecodeCompat(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
{
LZWCodecState *sp = DecoderState(tif);
char *op = (char*) op0;
long occ = (long) occ0;
char *tp;
u_char *bp;
int code, nbits;
long nextbits, nextdata, nbitsmask;
code_t *codep, *free_entp, *maxcodep, *oldcodep;
(void) s;
assert(sp != NULL);
/*
* Restart interrupted output operation.
*/
if (sp->dec_restart) {
long residue;
codep = sp->dec_codep;
residue = codep->length - sp->dec_restart;
if (residue > occ) {
/*
* Residue from previous decode is sufficient
* to satisfy decode request. Skip to the
* start of the decoded string, place decoded
* values in the output buffer, and return.
*/
sp->dec_restart += occ;
do {
codep = codep->next;
} while (--residue > occ);
tp = op + occ;
do {
*--tp = codep->value;
codep = codep->next;
} while (--occ);
return (1);
}
/*
* Residue satisfies only part of the decode request.
*/
op += residue, occ -= residue;
tp = op;
do {
*--tp = codep->value;
codep = codep->next;
} while (--residue);
sp->dec_restart = 0;
}
bp = (u_char *)tif->tif_rawcp;
nbits = sp->lzw_nbits;
nextdata = sp->lzw_nextdata;
nextbits = sp->lzw_nextbits;
nbitsmask = sp->dec_nbitsmask;
oldcodep = sp->dec_oldcodep;
free_entp = sp->dec_free_entp;
maxcodep = sp->dec_maxcodep;
while (occ > 0) {
NextCode(tif, sp, bp, code, GetNextCodeCompat);
if (code == CODE_EOI)
break;
if (code == CODE_CLEAR) {
free_entp = sp->dec_codetab + CODE_FIRST;
nbits = BITS_MIN;
nbitsmask = MAXCODE(BITS_MIN);
maxcodep = sp->dec_codetab + nbitsmask;
NextCode(tif, sp, bp, code, GetNextCodeCompat);
if (code == CODE_EOI)
break;
*op++ = (char) code, occ--;
oldcodep = sp->dec_codetab + code;
continue;
}
codep = sp->dec_codetab + code;
/*
* Add the new entry to the code table.
*/
if (free_entp < &sp->dec_codetab[0] ||
free_entp >= &sp->dec_codetab[CSIZE]) {
TIFFError(tif->tif_name,
"LZWDecodeCompat: Corrupted LZW table at scanline %d",
tif->tif_row);
return (0);
}
free_entp->next = oldcodep;
if (free_entp->next < &sp->dec_codetab[0] ||
free_entp->next >= &sp->dec_codetab[CSIZE]) {
TIFFError(tif->tif_name,
"LZWDecodeCompat: Corrupted LZW table at scanline %d",
tif->tif_row);
return (0);
}
free_entp->firstchar = free_entp->next->firstchar;
free_entp->length = free_entp->next->length+1;
free_entp->value = (codep < free_entp) ?
codep->firstchar : free_entp->firstchar;
if (++free_entp > maxcodep) {
if (++nbits > BITS_MAX) /* should not happen */
nbits = BITS_MAX;
nbitsmask = MAXCODE(nbits);
maxcodep = sp->dec_codetab + nbitsmask;
}
oldcodep = codep;
if (code >= 256) {
/*
* Code maps to a string, copy string
* value to output (written in reverse).
*/
if(codep->length == 0) {
TIFFError(tif->tif_name,
"LZWDecodeCompat: Wrong length of decoded "
"string: data probably corrupted at scanline %d",
tif->tif_row);
return (0);
}
if (codep->length > occ) {
/*
* String is too long for decode buffer,
* locate portion that will fit, copy to
* the decode buffer, and setup restart
* logic for the next decoding call.
*/
sp->dec_codep = codep;
do {
codep = codep->next;
} while (codep->length > occ);
sp->dec_restart = occ;
tp = op + occ;
do {
*--tp = codep->value;
codep = codep->next;
} while (--occ);
break;
}
op += codep->length, occ -= codep->length;
tp = op;
do {
*--tp = codep->value;
} while( (codep = codep->next) != NULL);
} else
*op++ = (char) code, occ--;
}
tif->tif_rawcp = (tidata_t) bp;
sp->lzw_nbits = (u_short) nbits;
sp->lzw_nextdata = nextdata;
sp->lzw_nextbits = nextbits;
sp->dec_nbitsmask = nbitsmask;
sp->dec_oldcodep = oldcodep;
sp->dec_free_entp = free_entp;
sp->dec_maxcodep = maxcodep;
if (occ > 0) {
TIFFError(tif->tif_name,
"LZWDecodeCompat: Not enough data at scanline %d (short %d bytes)",
tif->tif_row, occ);
return (0);
}
return (1);
}
#endif /* LZW_COMPAT */
static void
LZWCleanup(TIFF* tif)
{
if (tif->tif_data) {
if (DecoderState(tif)->dec_codetab)
_TIFFfree(DecoderState(tif)->dec_codetab);
_TIFFfree(tif->tif_data);
tif->tif_data = NULL;
}
}
static int
LZWSetupEncode(TIFF* tif)
{
TIFFError(tif->tif_name,
"LZW compression is not available to due to Unisys patent enforcement");
return (0);
}
int
TIFFInitLZW(TIFF* tif, int scheme)
{
assert(scheme == COMPRESSION_LZW);
/*
* Allocate state block so tag methods have storage to record values.
*/
tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (LZWCodecState));
if (tif->tif_data == NULL)
goto bad;
DecoderState(tif)->dec_codetab = NULL;
DecoderState(tif)->dec_decode = NULL;
/*
* Install codec methods.
*/
tif->tif_setupencode = LZWSetupEncode;
tif->tif_setupdecode = LZWSetupDecode;
tif->tif_predecode = LZWPreDecode;
tif->tif_decoderow = LZWDecode;
tif->tif_decodestrip = LZWDecode;
tif->tif_decodetile = LZWDecode;
tif->tif_cleanup = LZWCleanup;
/*
* Setup predictor setup.
*/
(void) TIFFPredictorInit(tif);
return (1);
bad:
TIFFError("TIFFInitLZW", "No space for LZW state block");
return (0);
}
/*
* Copyright (c) 1985, 1986 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* James A. Woods, derived from original work by Spencer Thomas
* and Joseph Orost.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#endif /* LZW_SUPPORT */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?