Ejemplo n.º 1
0
static int
LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
{
	static const char module[] = "LZWDecodeCompat";
	LZWCodecState *sp = DecoderState(tif);
	char *op = (char*) op0;
	long occ = (long) occ0;
	char *tp;
	unsigned char *bp;
	int code, nbits;
	long nextbits, nextdata, nbitsmask;
	code_t *codep, *free_entp, *maxcodep, *oldcodep;

	(void) s;
	assert(sp != NULL);

	/*
	  Fail if value does not fit in long.
	*/
	if ((tmsize_t) occ != occ0)
	        return (0);

	/*
	 * 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 = (unsigned char *)tif->tif_rawcp;
#ifdef LZW_CHECKEOS
	sp->dec_bitsleft = (((uint64)tif->tif_rawcc) << 3);
#endif
	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) {
			do {
				free_entp = sp->dec_codetab + CODE_FIRST;
				_TIFFmemset(free_entp, 0,
					    (CSIZE - CODE_FIRST) * sizeof (code_t));
				nbits = BITS_MIN;
				nbitsmask = MAXCODE(BITS_MIN);
				maxcodep = sp->dec_codetab + nbitsmask;
				NextCode(tif, sp, bp, code, GetNextCodeCompat);
			} while (code == CODE_CLEAR);	/* consecutive CODE_CLEAR codes */
			if (code == CODE_EOI)
				break;
			if (code > CODE_CLEAR) {
				TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
				"LZWDecode: Corrupted LZW table at scanline %d",
					     tif->tif_row);
				return (0);
			}
			*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]) {
			TIFFErrorExt(tif->tif_clientdata, module,
			    "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]) {
			TIFFErrorExt(tif->tif_clientdata, module,
			    "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) {
				TIFFErrorExt(tif->tif_clientdata, module,
				    "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;
			}
			assert(occ >= codep->length);
			op += codep->length;
			occ -= codep->length;
			tp = op;
			do {
				*--tp = codep->value;
			} while( (codep = codep->next) != NULL );
		} else {
			*op++ = (char)code;
			occ--;
		}
	}

	tif->tif_rawcc -= (tmsize_t)( (uint8*) bp - tif->tif_rawcp );
	tif->tif_rawcp = (uint8*) bp;
	sp->lzw_nbits = (unsigned 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) {
#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
		TIFFErrorExt(tif->tif_clientdata, module,
			"Not enough data at scanline %d (short %I64d bytes)",
			     tif->tif_row, (unsigned __int64) occ);
#else
		TIFFErrorExt(tif->tif_clientdata, module,
			"Not enough data at scanline %d (short %llu bytes)",
			     tif->tif_row, (unsigned long long) occ);
#endif
		return (0);
	}
	return (1);
}
Ejemplo n.º 2
0
bool
GIFLoad::ReadGIFImageData()
{
	unsigned char newEntry[ENTRY_COUNT];
	unsigned char codeSize;
	if (fInput->Read(&codeSize, 1) < 1)
		return false;

	if (codeSize > fPalette->size_in_bits) {
		if (debug) {
			syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - "
				"Code_size should be %d, not %d, allowing it\n",
				fCodeSize, codeSize);
		}
		if (!InitFrame(codeSize))
			return false;
	} else if (codeSize < fPalette->size_in_bits) {
		if (debug) {
			syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - "
				"Code_size should be %d, not %d\n", fCodeSize, codeSize);
		}
		return false;
	} else if (!InitFrame(fPalette->size_in_bits))
		return false;

	if (debug)
		syslog(LOG_INFO, "GIFLoad::ReadGIFImageData() - Starting LZW\n");

	while ((fNewCode = NextCode()) != -1 && fNewCode != fEndCode) {
		if (fNewCode == fClearCode) {
			ResetTable();
			fNewCode = NextCode();
			fOldCode[0] = fNewCode;
			fOldCodeLength = 1;
			if (!OutputColor(fOldCode, 1))
				goto bad_end;

			if (fNewCode == -1 || fNewCode == fEndCode) {
				if (debug) {
					syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - "
						"Premature fEndCode or error reading fNewCode\n");
				}
				goto bad_end;
			}
			continue;
		}

		// explicitly check for lack of clear code at start of file
		if (fOldCodeLength == 0) {
			fOldCode[0] = fNewCode;
			fOldCodeLength = 1;
			if (!OutputColor(fOldCode, 1))
				goto bad_end;

			continue;
		}

		// error out if we're trying to access an out-of-bounds index
		if (fNextCode >= ENTRY_COUNT)
			goto bad_end;

		if (fTable[fNewCode] != NULL) {
			// exists in table

			if (!OutputColor(fTable[fNewCode], fEntrySize[fNewCode]))
				goto bad_end;

			//memcpy(newEntry, fOldCode, fOldCodeLength);
			for (unsigned int x = 0; x < fOldCodeLength; x++)
				newEntry[x] = fOldCode[x];

			//memcpy(newEntry + fOldCodeLength, fTable[fNewCode], 1);
			newEntry[fOldCodeLength] = fTable[fNewCode][0];
		} else {
			// does not exist in table

			//memcpy(newEntry, fOldCode, fOldCodeLength);
			for (unsigned int x = 0; x < fOldCodeLength; x++)
				newEntry[x] = fOldCode[x];

			//memcpy(newEntry + fOldCodeLength, fOldCode, 1);
			newEntry[fOldCodeLength] = fOldCode[0];

			if (!OutputColor(newEntry, fOldCodeLength + 1))
				goto bad_end;
		}
		fTable[fNextCode] = MemblockAllocate(fOldCodeLength + 1);
		if (fTable[fNextCode] == NULL)
			goto bad_end;

		//memcpy(fTable[fNextCode], newEntry, fOldCodeLength + 1);
		for (unsigned int x = 0; x < fOldCodeLength + 1; x++)
			fTable[fNextCode][x] = newEntry[x];

		fEntrySize[fNextCode] = fOldCodeLength + 1;

		//memcpy(fOldCode, fTable[fNewCode], fEntrySize[fNewCode]);
		for (int x = 0; x < fEntrySize[fNewCode]; x++)
			fOldCode[x] = fTable[fNewCode][x];

		fOldCodeLength = fEntrySize[fNewCode];
		fNextCode++;

		if (fNextCode > fMaxCode && fBits < LZ_MAX_BITS) {
			fBits++;
			fMaxCode = (1 << fBits) - 1;
		}
	}

	MemblockDeleteAll();
	if (fNewCode == -1)
		return false;

	if (debug)
		syslog(LOG_INFO, "GIFLoad::ReadGIFImageData() - Done\n");

	return true;

bad_end:
	if (debug)
		syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - Reached a bad end\n");

	MemblockDeleteAll();
	return false;
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
bool
GIFLoad::ReadGIFImageData() 
{
	unsigned char newEntry[4096];
	
	unsigned char cs;
	fInput->Read(&cs, 1);
	if (cs == fPalette->size_in_bits) {
		if (!InitFrame(fPalette->size_in_bits))
			return false;
	} else if (cs > fPalette->size_in_bits) {
		if (debug)
			syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - Code_size should be %d, not "
				"%d, allowing it\n", fCodeSize, cs);
		if (!InitFrame(cs))
			return false;
	} else if (cs < fPalette->size_in_bits) {
		if (debug)
			syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - Code_size should be %d, not "
				"%d\n", fCodeSize, cs);
		return false;
	}
	
	if (debug)
		syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - Starting LZW\n");
	
	while ((fNewCode = NextCode()) != -1 && fNewCode != fEndCode) {
		if (fNewCode == fClearCode) {
			ResetTable();
			fNewCode = NextCode();
			fOldCode[0] = fNewCode;
			fOldCodeLength = 1;
			if (!OutputColor(fOldCode, 1)) goto bad_end;
			if (fNewCode == -1 || fNewCode == fEndCode) {
				if (debug)
					syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - Premature fEndCode "
						"or error\n");
				goto bad_end;
			}
			continue;
		}
		
		// Explicitly check for lack of clear code at start of file
		if (fOldCodeLength == 0) {
			fOldCode[0] = fNewCode;
			fOldCodeLength = 1;
			if (!OutputColor(fOldCode, 1))
				goto bad_end;
			continue;
		}
		
		if (fTable[fNewCode] != NULL) { // Does exist in table
			if (!OutputColor(fTable[fNewCode], fEntrySize[fNewCode]))
				goto bad_end;
			
			//memcpy(newEntry, fOldCode, fOldCodeLength);
			for (int x = 0; x < fOldCodeLength; x++) {
				newEntry[x] = fOldCode[x];
			}
			
			//memcpy(newEntry + fOldCodeLength, fTable[fNewCode], 1);
			newEntry[fOldCodeLength] = *fTable[fNewCode];
		} else { // Does not exist in table
			//memcpy(newEntry, fOldCode, fOldCodeLength);
			for (int x = 0; x < fOldCodeLength; x++) {
				newEntry[x] = fOldCode[x];
			}
			
			//memcpy(newEntry + fOldCodeLength, fOldCode, 1);
			newEntry[fOldCodeLength] = *fOldCode;
			
			if (!OutputColor(newEntry, fOldCodeLength + 1))
				goto bad_end;
		}
		fTable[fNextCode] = MemblockAllocate(fOldCodeLength + 1);

		//memcpy(fTable[fNextCode], newEntry, fOldCodeLength + 1);
		for (int x = 0; x < fOldCodeLength + 1; x++) {
			fTable[fNextCode][x] = newEntry[x];
		}
		
		fEntrySize[fNextCode] = fOldCodeLength + 1;
		
		//memcpy(fOldCode, fTable[fNewCode], fEntrySize[fNewCode]);
		for (int x = 0; x < fEntrySize[fNewCode]; x++) {
			fOldCode[x] = fTable[fNewCode][x];
		}
		
		fOldCodeLength = fEntrySize[fNewCode];
		fNextCode++;
		
		if (fNextCode > fMaxCode && fBits != 12) {
			fBits++;
			fMaxCode = (1 << fBits) - 1;
		}
	}

	MemblockDeleteAll();
	if (fNewCode == -1)
		return false;
	if (debug)
		syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - Done\n");
	return true;
	
bad_end:
	if (debug)
		syslog(LOG_ERR, "GIFLoad::ReadGIFImageData() - Reached a bad end\n");
	MemblockDeleteAll();
	return false;
}