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

📄 gifdecoderapi.c

📁 gif图像文件软件解码器的arm版本的源代码程序
💻 C
字号:
///////////////////////////////////////////////////////////////////////////////
//
//  gifdecoderapi.h
//
//  DESCRIPTION
//         Define functions that implements the GIF Decoder API.      
//
//
///////////////////////////////////////////////////////////////////////////////


#include "gifdecoderapi.h"
#include "gifcommon.h"

// global variable 
static Image *currentImage;

// external
extern Image *ReadGIFFrame
(
    const Image *image, 
    unsigned char *outbuf,
    ImageSaveMethod saveimage, 
    unsigned char skipdecoding,
    OP_BOOLEAN    only_info,
    OP_BOOLEAN func(OP_UINT16 x, OP_UINT16 y)
);

extern Image *ReadGIFHeader
(
    const Image *image_info
);

#define RGB565(r, g, b) ((r >> 3) << 11)| ((g >> 2) << 5)| ((b >> 3) << 0)

// function pointer type definition
typedef void* (*GetMemoryFunction)(OP_UINT32 size);
typedef void (*FreeMemoryFunction)(void *x);

// Global variables

// input buffer pointer
static OP_UINT8             *gifInputBuffer;

// output buffer pointer;
static OP_UINT8             *gifOutputBuffer;

// input buffer size
static OP_UINT32            gifInputBufferSize;

// image information
static GIF_IMAGE_INFO       gifImageInfo;

// memory allocation function pointer
static GetMemoryFunction    gifDynMemAllocate; 

// memory deallocate function pointer
static FreeMemoryFunction   gifDynMemDeallocate;

// decoder state
static GIF_DECODER_STATE    gifDecoderState = GIF_DECODER_STATE_UNINITIALIZED;

// GIF Decoder API Functions

/////////////////////////////////////////////////////////////////////////////
// NAME  
//            gifDecoderInitialize
//
// DESCRIPTION
//            This function initializes the GIF Decoder and sets the image  
//            decoding configurations to default values.
//            
// INPUTS   
//            none.        
//
// OUTPUTS  
//            none.    
//
// RETURN VALUE
//          none.
//           
/////////////////////////////////////////////////////////////////////////////
void  gifDecoderInitialize 
(
    void
)
{
    // clear input and output buffer pointers
    gifInputBuffer = 0;
    gifOutputBuffer = 0;
    gifInputBufferSize = 0;

    // clear image info structure
    gifImageInfo.imageWidth = 0;    
    gifImageInfo.imageHeight = 0;                   
    gifImageInfo.logicalScreenWidth = 0;            
    gifImageInfo.logicalScreenHeight = 0;            
    gifImageInfo.imageLeftPos = 0;                
    gifImageInfo.imageTopPos = 0;                    
    gifImageInfo.imageDelay = 0;                    
    gifImageInfo.imageIterations = 0;
    gifImageInfo.backgroundColor = 0;
    gifImageInfo.disposal = 0;
    gifImageInfo.trans_flag = OP_FALSE;
    gifImageInfo.comments[0] = 0;
    
    // clear image pointer
    currentImage = OP_NULL;

    // update decoder state
    gifDecoderState = GIF_DECODER_STATE_INITIALIZED;
}

/////////////////////////////////////////////////////////////////////////////
// NAME  
//            gifSetInputBuffer
//
// DESCRIPTION
//            This function allows the Decoder Controller to pass the decoder
//            the input buffer pointer and the input buffer size
//            
// INPUTS   
//            inputBuffer - input buffer pointer
//            bufferSize - input buffer size        
//
// OUTPUTS  
//            none.    
//
// RETURN VALUE
//          none.
//           
/////////////////////////////////////////////////////////////////////////////
void  gifSetInputBuffer
(
    OP_UINT8    *inputBuffer, 
    OP_UINT32   bufferSize
)
{
        OP_UINT16           i;
        Image               image0;
        Image               *image1; 
        Image               *image2;

        // store input buffer info
        gifInputBuffer = inputBuffer;
        gifInputBufferSize = bufferSize;

        // get GIF image size information
        for(i = 0; i < sizeof(Image); i++)
        {
            ((OP_UINT8 *)&image0)[i] = 0;
        }
        image0.getmemory = gifDynMemAllocate;
        image0.freememory = gifDynMemDeallocate;
        image1 = AllocateImage(&image0);

        image1->blob->data = gifInputBuffer;
        image1->blob->offset = 0;
        image1->blob->length = gifInputBufferSize;

        currentImage = ReadGIFHeader(image1);
        DestroyImage(image1);

        if(currentImage == OP_NULL)
        {
            return; 
        }

        // get GIF image info
        image1 = AllocateImage(currentImage);
        if(image1 == OP_NULL) 
        {
            return;
        }
        image2 = ReadGIFFrame(image1, OP_NULL, OP_NULL, OP_TRUE, OP_FALSE, OP_NULL);
        if(image2 == OP_NULL)
        {
            DestroyImage(image1);
            return;
        }

        // copy image size, location and logical screen size
        gifImageInfo.imageWidth = image2->columns;
        gifImageInfo.imageHeight = image2->rows;
        gifImageInfo.logicalScreenWidth = image2->page.width;            
        gifImageInfo.logicalScreenHeight = image2->page.height;            
        gifImageInfo.imageLeftPos = image2->page.x;                
        gifImageInfo.imageTopPos = image2->page.y;    
        gifImageInfo.imageDelay = image2->delay * 10;                    
        gifImageInfo.imageIterations = image2->iterations;

        gifImageInfo.backgroundColor = RGB565(image2->background_color.red,  
                                              image2->background_color.green, 
                                              image2->background_color.blue);

        gifImageInfo.disposal = image2->dispose;

        gifImageInfo.trans_flag = image2->trans_flag;

        // free memory
        if(image2 != image1) 
        {
            DestroyImage(image2);
        }
        DestroyImage(image1);

        // update decoder state
        gifDecoderState = GIF_DECODER_STATE_READY;

}


/////////////////////////////////////////////////////////////////////////////
// NAME  
//            gifGetImageInfo
//
// DESCRIPTION
//            This function returns image information to Image Decoder 
//            Controller
//            
// INPUTS   
//            info - pointer to GIF image info structure    
//
// OUTPUTS  
//            info - update value in this structure.    
//
// RETURN VALUE
//          GIF_DECODER_ERR_NONE if successful, an error code otherwise.
//           
/////////////////////////////////////////////////////////////////////////////
GIF_DECODER_ERR  gifGetImageInfo 
(
    GIF_IMAGE_INFO  *info
)
{
    // check if we are in the right state
    if(gifDecoderState == GIF_DECODER_STATE_READY)
    {
        // copy image info
        info->imageWidth = gifImageInfo.imageWidth;
        info->imageHeight = gifImageInfo.imageHeight;
        info->logicalScreenWidth = gifImageInfo.logicalScreenWidth;         
        info->logicalScreenHeight = gifImageInfo.logicalScreenHeight;            
        info->imageLeftPos = gifImageInfo.imageLeftPos;     
        info->imageTopPos = gifImageInfo.imageTopPos; 
        info->imageDelay = gifImageInfo.imageDelay;     
        info->imageIterations = gifImageInfo.imageIterations;
        info->backgroundColor = gifImageInfo.backgroundColor;
        info->disposal = gifImageInfo.disposal;
        info->trans_flag = gifImageInfo.trans_flag;

        return GIF_DECODER_ERR_NONE;
    }
    else
    {
        return GIF_DECODER_ERR_INVALID_STATE;
    }

}    


/////////////////////////////////////////////////////////////////////////////
// NAME  
//            gifDecodeImage
//
// DESCRIPTION
//            This function decodes a frame in the GIF image
//            
// INPUTS   
//            outputBuffer - output buffer pointer
//            func - callback function    
//            lastFrame - indicates whether this is the last frame in image    
//
// OUTPUTS  
//            outputBuffer - store result to output buffer    
//
// RETURN VALUE
//          GIF_DECODER_ERR_NONE if successful, an error code otherwise.
//           
/////////////////////////////////////////////////////////////////////////////
GIF_DECODER_ERR  gifDecodeImage
(
    OP_UINT8        *outputBuffer, 
    OP_BOOLEAN      func(OP_UINT16 x, OP_UINT16 y), 
    OP_BOOLEAN      *lastFrame,
    OP_BOOLEAN      only_info
)
{
    // check if we are in the right state
    if(gifDecoderState == GIF_DECODER_STATE_READY)
    {

        Image               *image1;
        Image               *image2;

        // save output buffer pointer
        gifOutputBuffer = outputBuffer;

        // update decoder state
        gifDecoderState = GIF_DECODER_STATE_ACTIVE;

        // start GIF decoding
        image1 = ReadGIFFrame(currentImage, outputBuffer, OP_NULL, only_info, only_info, func);

        if(image1 != OP_NULL)
        {
            // free memory if necessary
            if(image1 != currentImage)
            {
                DestroyImage(currentImage);
            }
            currentImage = image1;

            // check if there is more frame
            image1 = AllocateImage(currentImage);
            if(image1 == OP_NULL) 
            {
                return GIF_DECODER_ERR_OPERATION_FAILED;
            }
            image2 = ReadGIFFrame(image1, OP_NULL, OP_NULL, OP_TRUE, OP_FALSE, OP_NULL);
            if(image2 == OP_NULL)
            {
                // if no more frame, return
                *lastFrame = OP_TRUE;
                DestroyImage(image1);
                return GIF_DECODER_ERR_NONE;
            }

            // otherwise update image info
            *lastFrame = OP_FALSE;

            // copy image size, location and logical screen size
            gifImageInfo.imageWidth = image2->columns;
            gifImageInfo.imageHeight = image2->rows;
            gifImageInfo.logicalScreenWidth = image2->page.width;            
            gifImageInfo.logicalScreenHeight = image2->page.height;            
            gifImageInfo.imageLeftPos = image2->page.x;                
            gifImageInfo.imageTopPos = image2->page.y;    
            gifImageInfo.imageDelay = image2->delay * 10;                    
            gifImageInfo.imageIterations = image2->iterations;

            gifImageInfo.backgroundColor = RGB565(image2->background_color.red,  
                                                  image2->background_color.green, 
                                                  image2->background_color.blue);

            gifImageInfo.disposal = image2->dispose;

            // free memory
            if(image2 != image1) 
            {
                DestroyImage(image2);
            }
            DestroyImage(image1);
        
            // update decoder state
            gifDecoderState = GIF_DECODER_STATE_READY;

            return GIF_DECODER_ERR_NONE;
        }
        else 
        {
            /* 
            * Remove DestroyImage() because of duplicated free memory in ReadGIFFrame()
            * // free memory if necessary
            * if(currentImage->next != OP_NULL)
            * {
            *     DestroyImage(currentImage->next);
            * }
            */
            *lastFrame = OP_TRUE;

            // update decoder state
            gifDecoderState = GIF_DECODER_STATE_READY;

            return GIF_DECODER_ERR_OPERATION_FAILED;
        }
    }
    else
    {
        return GIF_DECODER_ERR_INVALID_STATE;
    }
}    


/////////////////////////////////////////////////////////////////////////////
// NAME  
//            gifSetDynMemAllocFuncs
//
// DESCRIPTION
//            This function allows the Decoder Controller to pass the dynamic
//            memory allocation function pointers to the decoder
//            
// INPUTS   
//            allocate - memory allocation function pointer
//            deallocate - memory deallocation function pointer        
//
// OUTPUTS  
//            none.    
//
// RETURN VALUE
//          none.
//           
/////////////////////////////////////////////////////////////////////////////
void  gifSetDynMemAllocFuncs
(
    void    *allocate(OP_UINT32 size), 
    void    deallocate(void *x)
)
{
    gifDynMemAllocate = allocate;
    gifDynMemDeallocate = deallocate;
}

/////////////////////////////////////////////////////////////////////////////
// NAME  
//            gifDecoderCleanup
//
// DESCRIPTION
//            This function releases all dynamic memory resources allocated
//            during decoding
//            
// INPUTS   
//            none.        
//
// OUTPUTS  
//            none.    
//
// RETURN VALUE
//          none.
//           
/////////////////////////////////////////////////////////////////////////////
void  gifDecoderCleanup
(
    void
)
{
    if(currentImage != OP_NULL)
    {
        DestroyImage(currentImage);
    }
    currentImage = OP_NULL;
}

⌨️ 快捷键说明

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