⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dgif_lib.c

📁 Sigma SMP8634 Mrua v. 2.8.2.0
💻 C
📖 第 1 页 / 共 3 页
字号:
    Prefix = Private->Prefix;    for (i = 0; i <= LZ_MAX_CODE; i++)        Prefix[i] = NO_SUCH_CODE;    return GIF_OK;}/****************************************************************************** * The LZ decompression routine: * This version decompress the given gif file into Line of length LineLen. * This routine can be called few times (one per scan line, for example), in * order the complete the whole image. *****************************************************************************/static intDGifDecompressLine(GifFileType * GifFile,                   GifPixelType * Line,                   int LineLen) {    int i = 0;    int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;    GifByteType *Stack, *Suffix;    GifPrefixType *Prefix;    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;    StackPtr = Private->StackPtr;    Prefix = Private->Prefix;    Suffix = Private->Suffix;    Stack = Private->Stack;    EOFCode = Private->EOFCode;    ClearCode = Private->ClearCode;    LastCode = Private->LastCode;    if (StackPtr != 0) {        /* Let pop the stack off before continueing to read the gif file: */        while (StackPtr != 0 && i < LineLen)            Line[i++] = Stack[--StackPtr];    }    while (i < LineLen) {    /* Decode LineLen items. */        if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)            return GIF_ERROR;        if (CrntCode == EOFCode) {            /* Note however that usually we will not be here as we will stop             * decoding as soon as we got all the pixel, or EOF code will             * not be read at all, and DGifGetLine/Pixel clean everything.  */            if (i != LineLen - 1 || Private->PixelCount != 0) {                _GifError = D_GIF_ERR_EOF_TOO_SOON;                return GIF_ERROR;            }            i++;        } else if (CrntCode == ClearCode) {            /* We need to start over again: */            for (j = 0; j <= LZ_MAX_CODE; j++)                Prefix[j] = NO_SUCH_CODE;            Private->RunningCode = Private->EOFCode + 1;            Private->RunningBits = Private->BitsPerPixel + 1;            Private->MaxCode1 = 1 << Private->RunningBits;            LastCode = Private->LastCode = NO_SUCH_CODE;        } else {            /* Its regular code - if in pixel range simply add it to output             * stream, otherwise trace to codes linked list until the prefix             * is in pixel range: */            if (CrntCode < ClearCode) {                /* This is simple - its pixel scalar, so add it to output: */                Line[i++] = CrntCode;            } else {                /* Its a code to needed to be traced: trace the linked list                 * until the prefix is a pixel, while pushing the suffix                 * pixels on our stack. If we done, pop the stack in reverse                 * (thats what stack is good for!) order to output.  */                if (Prefix[CrntCode] == NO_SUCH_CODE) {                    /* Only allowed if CrntCode is exactly the running code:                     * In that case CrntCode = XXXCode, CrntCode or the                     * prefix code is last code and the suffix char is                     * exactly the prefix of last code! */                    if (CrntCode == Private->RunningCode - 2) {                        CrntPrefix = LastCode;                        Suffix[Private->RunningCode - 2] =                           Stack[StackPtr++] = DGifGetPrefixChar(Prefix,                                                                 LastCode,                                                                 ClearCode);                    } else {                        _GifError = D_GIF_ERR_IMAGE_DEFECT;                        return GIF_ERROR;                    }                } else                    CrntPrefix = CrntCode;                /* Now (if image is O.K.) we should not get an NO_SUCH_CODE                 * During the trace. As we might loop forever, in case of                 * defective image, we count the number of loops we trace                 * and stop if we got LZ_MAX_CODE. obviously we can not                 * loop more than that.  */                j = 0;                while (j++ <= LZ_MAX_CODE &&                       CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {                    Stack[StackPtr++] = Suffix[CrntPrefix];                    CrntPrefix = Prefix[CrntPrefix];                }                if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {                    _GifError = D_GIF_ERR_IMAGE_DEFECT;                    return GIF_ERROR;                }                /* Push the last character on stack: */                Stack[StackPtr++] = CrntPrefix;                /* Now lets pop all the stack into output: */                while (StackPtr != 0 && i < LineLen)                    Line[i++] = Stack[--StackPtr];            }            if (LastCode != NO_SUCH_CODE) {                Prefix[Private->RunningCode - 2] = LastCode;                if (CrntCode == Private->RunningCode - 2) {                    /* Only allowed if CrntCode is exactly the running code:                     * In that case CrntCode = XXXCode, CrntCode or the                     * prefix code is last code and the suffix char is                     * exactly the prefix of last code! */                    Suffix[Private->RunningCode - 2] =                       DGifGetPrefixChar(Prefix, LastCode, ClearCode);                } else {                    Suffix[Private->RunningCode - 2] =                       DGifGetPrefixChar(Prefix, CrntCode, ClearCode);                }            }            LastCode = CrntCode;        }    }    Private->LastCode = LastCode;    Private->StackPtr = StackPtr;    return GIF_OK;}/****************************************************************************** * Routine to trace the Prefixes linked list until we get a prefix which is * not code, but a pixel value (less than ClearCode). Returns that pixel value. * If image is defective, we might loop here forever, so we limit the loops to * the maximum possible if image O.k. - LZ_MAX_CODE times. *****************************************************************************/static intDGifGetPrefixChar(GifPrefixType *Prefix,                  int Code,                  int ClearCode) {    int i = 0;    while (Code > ClearCode && i++ <= LZ_MAX_CODE)        Code = Prefix[Code];    return Code;}/****************************************************************************** * Interface for accessing the LZ codes directly. Set Code to the real code * (12bits), or to -1 if EOF code is returned. *****************************************************************************/intDGifGetLZCodes(GifFileType * GifFile,               int *Code) {        GifByteType *CodeBlock;    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;    if (!IS_READABLE(Private)) {        /* This file was NOT open for reading: */        _GifError = D_GIF_ERR_NOT_READABLE;        return GIF_ERROR;    }    if (DGifDecompressInput(GifFile, Code) == GIF_ERROR)        return GIF_ERROR;    if (*Code == Private->EOFCode) {        /* Skip rest of codes (hopefully only NULL terminating block): */        do {            if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR)                return GIF_ERROR;        } while (CodeBlock != NULL) ;        *Code = -1;    } else if (*Code == Private->ClearCode) {        /* We need to start over again: */        Private->RunningCode = Private->EOFCode + 1;        Private->RunningBits = Private->BitsPerPixel + 1;        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 intDGifDecompressInput(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    };    /* The image can't contain more than LZ_BITS per code. */    if (Private->RunningBits > LZ_BITS) {        _GifError = 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;}/****************************************************************************** * This routines read one gif data block at a time and buffers it internally * so that the decompression routine could access it. * The routine returns the next byte from its internal buffer (or read next * block in if buffer empty) and returns GIF_OK if succesful. *****************************************************************************/static intDGifBufferedInput(GifFileType * GifFile,                  GifByteType * Buf,                  GifByteType * NextByte) {    if (Buf[0] == 0) {        /* Needs to read the next buffer - this one is empty: */        if (READ(GifFile, Buf, 1) != 1) {            _GifError = D_GIF_ERR_READ_FAILED;            return GIF_ERROR;        }        /* There shouldn't be any empty data blocks here as the LZW spec         * says the LZW termination code should come first.  Therefore we         * shouldn't be inside this routine at that point.         */        if (Buf[0] == 0) {            _GifError = D_GIF_ERR_IMAGE_DEFECT;            return GIF_ERROR;        }        if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {            _GifError = D_GIF_ERR_READ_FAILED;            return GIF_ERROR;        }        *NextByte = Buf[1];        Buf[1] = 2;    /* We use now the second place as last char read! */        Buf[0]--;    } else {        *NextByte = Buf[Buf[1]++];        Buf[0]--;    }    return GIF_OK;}#ifndef _GBA_NO_FILEIO/****************************************************************************** * This routine reads an entire GIF into core, hanging all its state info off * the GifFileType pointer.  Call DGifOpenFileName() or DGifOpenFileHandle() * first to initialize I/O.  Its inverse is EGifSpew(). ******************************************************************************/intDGifSlurp(GifFileType * GifFile) {    int ImageSize;    GifRecordType RecordType;    SavedImage *sp;    GifByteType *ExtData;    SavedImage temp_save;    temp_save.ExtensionBlocks = NULL;    temp_save.ExtensionBlockCount = 0;    do {        if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)            return (GIF_ERROR);        switch (RecordType) {          case IMAGE_DESC_RECORD_TYPE:              if (DGifGetImageDesc(GifFile) == GIF_ERROR)                  return (GIF_ERROR);              sp = &GifFile->SavedImages[GifFile->ImageCount - 1];              ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;              sp->RasterBits = (unsigned char *)malloc(ImageSize *                                                       sizeof(GifPixelType));              if (sp->RasterBits == NULL) {                  return GIF_ERROR;              }              if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) ==                  GIF_ERROR)                  return (GIF_ERROR);              if (temp_save.ExtensionBlocks) {                  sp->ExtensionBlocks = temp_save.ExtensionBlocks;                  sp->ExtensionBlockCount = temp_save.ExtensionBlockCount;                  temp_save.ExtensionBlocks = NULL;                  temp_save.ExtensionBlockCount = 0;                  /* FIXME: The following is wrong.  It is left in only for                   * backwards compatibility.  Someday it should go away. Use                    * the sp->ExtensionBlocks->Function variable instead. */                  sp->Function = sp->ExtensionBlocks[0].Function;              }              break;          case EXTENSION_RECORD_TYPE:              if (DGifGetExtension(GifFile, &temp_save.Function, &ExtData) ==                  GIF_ERROR)                  return (GIF_ERROR);              while (ExtData != NULL) {                  /* Create an extension block with our data */                  if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1])                      == GIF_ERROR)                      return (GIF_ERROR);                  if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)                      return (GIF_ERROR);                  temp_save.Function = 0;              }              break;          case TERMINATE_RECORD_TYPE:              break;          default:    /* Should be trapped by DGifGetRecordType */              break;        }    } while (RecordType != TERMINATE_RECORD_TYPE);    /* Just in case the Gif has an extension block without an associated     * image... (Should we save this into a savefile structure with no image     * instead? Have to check if the present writing code can handle that as     * well.... */    if (temp_save.ExtensionBlocks)        FreeExtension(&temp_save);    return (GIF_OK);}#endif /* _GBA_NO_FILEIO */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -