static int DGifDecompressInput(GifFileType * GifFile, int *Code) { GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private; GifByteType NextByte; static unsigned short CodeMasks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff }; if (Private->RunningBits > LZ_BITS) { _GifError = D_GIF_ERR_IMAGE_DEFECT; return GIF_ERROR; } while (Private->CrntShiftState < Private->RunningBits) { if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) { return GIF_ERROR; } Private->CrntShiftDWord |= ((unsigned long) NextByte) << Private->CrntShiftState; Private->CrntShiftState += 8; } *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits]; Private->CrntShiftDWord >>= Private->RunningBits; Private->CrntShiftState -= Private->RunningBits; if (Private->RunningCode < LZ_MAX_CODE + 2 && ++Private->RunningCode > Private->MaxCode1 && Private->RunningBits < LZ_BITS) { Private->MaxCode1 <<= 1; Private->RunningBits++; } return GIF_OK; }
/****************************************************************************** * The LZ decompression input routine: * * This routine is responsable for the decompression of the bit stream from * * 8 bits (bytes) packets, into the real codes. * * Returns GIF_OK if read succesfully. * ******************************************************************************/ static int DGifDecompressInput(GifFilePrivateType *Private, int *Code) { GifByteType NextByte; static unsigned int CodeMasks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff }; while (Private->CrntShiftState < Private->RunningBits) { /* Needs to get more bytes from input stream for next code: */ if (DGifBufferedInput(Private, Private->Buf, &NextByte) == GIF_ERROR) { return GIF_ERROR; } Private->CrntShiftDWord |= ((u32) NextByte) << Private->CrntShiftState; Private->CrntShiftState += 8; } *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits]; Private->CrntShiftDWord >>= Private->RunningBits; Private->CrntShiftState -= Private->RunningBits; /* If code cannt fit into RunningBits bits, must raise its size. Note */ /* however that codes above 4095 are used for special signaling. */ if (++Private->RunningCode > Private->MaxCode1 && Private->RunningBits < LZ_BITS) { Private->MaxCode1 <<= 1; Private->RunningBits++; } return GIF_OK; }
/****************************************************************************** The LZ decompression input routine: This routine is responsable for the decompression of the bit stream from 8 bits (bytes) packets, into the real codes. Returns GIF_OK if read successfully. ******************************************************************************/ static int DGifDecompressInput(GifFileType *GifFile, int *Code) { static const unsigned short CodeMasks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff }; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; GifByteType NextByte; /* The image can't contain more than LZ_BITS per code. */ if (Private->RunningBits > LZ_BITS) { GifFile->Error = D_GIF_ERR_IMAGE_DEFECT; return GIF_ERROR; } while (Private->CrntShiftState < Private->RunningBits) { /* Needs to get more bytes from input stream for next code: */ if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) { return GIF_ERROR; } Private->CrntShiftDWord |= ((unsigned long)NextByte) << Private->CrntShiftState; Private->CrntShiftState += 8; } *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits]; Private->CrntShiftDWord >>= Private->RunningBits; Private->CrntShiftState -= Private->RunningBits; /* If code cannot fit into RunningBits bits, must raise its size. Note * however that codes above 4095 are used for special signaling. * If we're using LZ_BITS bits already and we're at the max code, just * keep using the table as it is, don't increment Private->RunningCode. */ if (Private->RunningCode < LZ_MAX_CODE + 2 && ++Private->RunningCode > Private->MaxCode1 && Private->RunningBits < LZ_BITS) { Private->MaxCode1 <<= 1; Private->RunningBits++; } return GIF_OK; }
/****************************************************************************** The LZ decompression input routine: This routine is responsable for the decompression of the bit stream from 8 bits (bytes) packets, into the real codes. Returns GIF_OK if read successfully. ******************************************************************************/ static int DGifDecompressInput(GifFileType *GifFile, int *Code) { static const unsigned short CodeMasks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff }; GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private; GifByteType NextByte; /* The image can't contain more than LZ_BITS per code. */ if (Private->RunningBits > LZ_BITS) { GifFile->Error = D_GIF_ERR_IMAGE_DEFECT; return GIF_ERROR; } /* * * 流程 * crntShiftState = 0; RunningBits = 3; NextByte = 01001011B; CrntShiftDWord = 0000000000000000B; * * CrntShiftDWord |= ((unsigned long) NextByte) << CrntShiftState; ---- CrntShiftDWord == 0000000001001011B; * * CrntShiftState += 8 ---- CrntShiftState == 8; * * Code = CrntShiftDWord & CodeMasks[RunningBits] ---- Code = 0000000001001011B & CodeMasks[3] ---- Code = 0000000001001011B & 111B ---- Code = 011B * * CrntShiftDWord >>= RunningBits ---- 0000000001001011B >>= 3 ---- CrntShiftDWord == 0000000000001001B; * * CrntShiftState -= RunningBits ---- 8 -= 3 ---- CrntShiftState == 5 * * 重复流程一次 * * NextByte = 01011100B; * * 由于这次 CrntShiftState > RunningBits 没有进入While循环 * * Code = CrntShiftDWord & CodeMasks[RunningBits] ---- Code = 0000000000001001B & CodeMasks[3] ---- Code = 0000000000001001B & 111B ---- Code = 001B * * CrntShiftDWord >>= RunningBits ---- 0000000000001001B >>= 3 ---- CrntShiftDWord == 0000000000000001B; * * CrntShiftState -= RunningBits ---- 5 -= 3 ---- CrntShiftState == 2; * * 重复流程第二次 * * NextByte = 10111111B; * * CrntShiftDWord |= ((unsigned long) NextByte) << CrntShiftState; ---- 0000000000000001B |= 10111111B << 2 ---- CrntShiftDWord == 0000001011111101B * * CrntShiftState += 8 ---- CrntShiftState = 10; * * Code = CrntShiftDWord & CodeMasks[RunningBits] ---- Code = 0000001011111101B & CodeMasks[3] ---- Code = 0000001011111101B & 111B ---- Code = 101B; * * CrntShiftDWord >>= RunningBits ---- 0000001011111101B >>= 3 ---- CrntShiftDWord == 0000000001011111B; * * CrntShiftState -= RunningBits ---- 10 -= 3 ---- CrntShiftState == 7; * * 由于LZW的每个code不是以字节为单位的, 在读取的时候使用了以上的技巧 用CrntShiftDWord作为读取出来的原始字节缓存 CrntShiftState作为读取Code的指针, * 每次读code的时候,如果缓存(CrntShiftDWord)不够code的长度(用CrntShiftState来做长度的判断),就读一个字节并放入缓存中(左移CrntShiftState位来防止覆盖掉原来缓存里的数据), * 缓存数据够的时候,用CodeMasks[RunningBits]来截取缓存中Code需要的长度, 并把缓存右移RunningBits位来清除掉已经读取的Code */ while (Private->CrntShiftState < Private->RunningBits) { /* Needs to get more bytes from input stream for next code: */ if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) { return GIF_ERROR; } Private->CrntShiftDWord |= ((unsigned long)NextByte) << Private->CrntShiftState; Private->CrntShiftState += 8; } *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits]; Private->CrntShiftDWord >>= Private->RunningBits; Private->CrntShiftState -= Private->RunningBits; /* If code cannot fit into RunningBits bits, must raise its size. Note * however that codes above 4095 are used for special signaling. * If we're using LZ_BITS bits already and we're at the max code, just * keep using the table as it is, don't increment Private->RunningCode. */ if (Private->RunningCode < LZ_MAX_CODE + 2 && ++Private->RunningCode > Private->MaxCode1 && Private->RunningBits < LZ_BITS) { Private->MaxCode1 <<= 1; Private->RunningBits++; } return GIF_OK; }