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

📄 irom_decodegifimage_arm.c

📁 gif图像文件软件解码器的arm版本的源代码程序
💻 C
字号:
///////////////////////////////////////////////////////////////////////////////
//
//  decode_image.c
//
//  DESCRIPTION
//        Define function for LZW decoding.
//
//
///////////////////////////////////////////////////////////////////////////////


/*
  Include declarations.
*/
#include    "OPUS_typedef.h"

#include    "irom_gifheader.h"
#include    "irom_gifdefine.h"
#include    "irom_gifclassify.h"
#include    "irom_gifimage.h"

#define EROM_TARGET

// inline functions
// generic bistream read function 
__inline unsigned int myReadBlob
(
    Image               *image,
    const unsigned int  length,
    unsigned char       **data
)
{
    unsigned int count;

    count = Min(length, image->blob->length - image->blob->offset);
    if(count != 0)
    {
        *data = image->blob->data + image->blob->offset;
        image->blob->offset += count;
    }
    return(count);
}

// read a byte from bitstream
__inline int myReadBlobByte
(
    Image   *image
)
{
    unsigned int      count;
    unsigned char     *tp;
    unsigned char     **p;

    p = &tp;

    count = myReadBlob(image, 1, p);
    if (count == 0)
    {
        return(0);
    }
    return(*tp);
}

// read a block from bitstream
__inline unsigned int myReadBlobBlock
(
    Image           *image,
    unsigned char   **data
)
{
    unsigned char     *tp;
    unsigned char     **p; 
    unsigned int      count;

    p = &tp;

    count = myReadBlob(image, 1, p);
    if (count == 0)
    {
        return(0);
    }
    return(myReadBlob(image, *tp, data));
}

/////////////////////////////////////////////////////////////////////////////
// NAME  
//            DecodeGIFImage
//
// DESCRIPTION
//            uncompresses an image via GIF-coding
//
// INPUTS   
//            image - the address of a structure of type Image
//            opacity - The colormap index associated with the transparent color
//            func - callback function to determine if we need to continue
//
// OUTPUTS  
//            none        
//
// RETURN VALUE
//          returns True if all the pixels are uncompressed without error, 
//            otherwise False.
//           
/////////////////////////////////////////////////////////////////////////////
unsigned int DecodeGIFImage
(
    Image           *image, 
    const long      opacity, 
    OP_BOOLEAN      func(OP_UINT16 x, OP_UINT16 y)
)
{
    #define MaxStackSize  4096
    #define NullCode  (-1)

    int     bits;
    int     code_size;
    int     offset;
    int     pass;

    long    available;
    long    code_mask;
    long    end_of_information;
    long    in_code;
    long    old_code;
    long    y;

    register long         code;
    register long       clear;

    register long       columns;
    register long       x;

    register unsigned int    *map;
    register unsigned int    *q;

    register unsigned char   *c;

    register unsigned long   datum;

    register unsigned int    count;

    register short           *prefix;

    unsigned char            data_size;
    unsigned char            first;
    unsigned char            *tp;
    unsigned char            **pp;
    unsigned char            *pixel_stack;

    register unsigned char         *top_stack;
    register unsigned char        *suffix;

#ifndef EROM_TARGET
        IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET

    pp = &tp;  
    map = (unsigned int*)image->colormap;  
    columns = image->columns;

#ifndef EROM_TARGET
        IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET
    /*
    Allocate decoder tables.
    */
    prefix = (short *) image->getmemory(MaxStackSize*sizeof(short));
    suffix = (unsigned char *) image->getmemory(MaxStackSize);
    pixel_stack = (unsigned char *) image->getmemory(MaxStackSize+1);

#ifndef EROM_TARGET
        IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET

    if ((prefix == (short *) OP_NULL) || (suffix == (unsigned char *) OP_NULL) ||
            (pixel_stack == (unsigned char *) OP_NULL))
    {
        if(pixel_stack != OP_NULL)
        {
            image->freememory(pixel_stack);
        }
        if(suffix != OP_NULL)
        {
            image->freememory(suffix);
        }
        if(prefix != OP_NULL)
        {
            image->freememory(prefix);
        }

        return OP_FALSE;
    }

#ifndef EROM_TARGET
        IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET

    /*
    Initialize GIF data stream decoder.
    */
    data_size = myReadBlobByte(image);
    if (data_size > 8)
    {
        image->freememory(pixel_stack);
        image->freememory(suffix);
        image->freememory(prefix);
        return OP_FALSE;
    }

#ifndef EROM_TARGET
        IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET

    clear = 1 << data_size;
    end_of_information = clear+1;
    available = clear+2;
    old_code = NullCode;
    code_size = data_size+1;
    code_mask = (1 << code_size)-1;

#ifndef EROM_TARGET
        IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET

    for (code=0; code < clear; code++)
    {
        prefix[code] = 0;
        suffix[code] = (unsigned char) code;
    }

#ifndef EROM_TARGET
        IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET
    /*
    Decode GIF pixel stream.
    */
    datum = 0;
    bits = 0;
    c = 0;
    count = 0;
    first = 0;
    offset = 0;
    pass = 0;
    top_stack = pixel_stack;

#ifndef EROM_TARGET
        IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET

    for (y=0; y < (long) image->rows; y++)
    {
        // check if we need to continue
        if(func != OP_NULL)
        {
            if(!func(x, y))
            {
                break;
            }
        }

        if(image->pixeldata == OP_NULL)
        {
            q = OP_NULL;
        }
        q = (unsigned int*)(image->pixeldata + image->columns * offset);
        if (q == (unsigned int *) OP_NULL)
        {
            break;
        }
        for (x=0; x < columns; )
        {
            if (top_stack == pixel_stack)
            {
                if (bits < code_size)
                {
                    /*
                      Load bytes until there is enough bits for a code.
                    */
                    if (count == 0)
                    {
                        /*
                          Read a new data block.
                        */
                        count = myReadBlobBlock(image,pp);
                        c = *pp;
                        if (count == 0)
                        {
                            break;
                        }
                    }
                    datum += (unsigned long) (*c++) << bits;
                    bits += 8;
                    count--;
                    if(count != 0)
                    {
                        datum += (unsigned long) (*c++) << bits;
                        bits += 8;
                        count--;
                    }
                    else
                    {
                        continue;
                    }
                }
                /*
                  Get the next code.
                */
                code = (long) (datum & code_mask);
                datum >>= code_size;
                bits -= code_size;
                /*
                  Interpret the code
                */
                if ((code > available) || (code == end_of_information))
                {
                    break;
                }
                if (code == clear)
                {
                    /*
                      Reset decoder.
                    */
                    code_size = data_size+1;
                    code_mask = (1 << code_size)-1;
                    available = clear+2;
                    old_code = NullCode;
                    continue;
                }
                if (old_code == NullCode)
                {
                    *top_stack++ = suffix[code];
                    old_code = code;
                    first = (unsigned char) code;
                    continue;
                }
                in_code = code;
                if (code >= available)
                {
                    *top_stack++ = first;
                    code = old_code;
                }
                while (code >= clear)
                {
                    *top_stack++ = suffix[code];
                    code = prefix[code];
                }
                first = suffix[code];
                /*
                  Add a new string to the string table,
                */
                if (available >= MaxStackSize)
                {
                    break;
                }
                *top_stack++ = first;
                prefix[available] = (short) old_code;
                suffix[available] = first;
                available++;
                if (((available & code_mask) == 0) && (available < MaxStackSize))
                {
                    code_size++;
                    code_mask += available;
                }
                old_code = in_code;
            }
            /*
              Pop a pixel off the pixel stack.
            */
            top_stack--;
            *q = map[*top_stack];
            *q = (*q & 0x00ffffffL) | 
                ((unsigned int)(*top_stack == opacity ? TransparentOpacity : OpaqueOpacity)) << 24;
            x++;
            q++;
        }
        if (image->interlace == NoInterlace)
        {
            offset++;
        }
        else
        {
            switch (pass)
            {
                case 0:
                default:
                {
                    offset += 8;
                    if (offset >= (long) image->rows)
                    {
                        pass++;
                        offset = 4;
                    }
                    break;
                }
                case 1:
                {
                    offset += 8;
                    if (offset >= (long) image->rows)
                    {
                        pass++;
                        offset = 2;
                    }
                    break;
                }
                case 2:
                {
                    offset += 4;
                    if (offset >= (long) image->rows)
                    {
                        pass++;
                        offset = 1;
                    }
                    break;
                }
                case 3:
                {
                    offset += 2;
                    break;
                }
            }
        }
        if (x < (long) image->columns)
        {
            break;
        }
    }

#ifndef EROM_TARGET
        IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET

    image->freememory(pixel_stack);
    image->freememory(suffix);
    image->freememory(prefix);

#ifndef EROM_TARGET
        IROM_CODE_CHECK_FEATURE_LOCK(FEATURE_LOCK_CHECK_MP3_JPEG);
#endif //EROM_TARGET

    if (y < (long) image->rows)
    {
        return OP_FALSE;
    }
    return(OP_TRUE);
}


/////////////////////////////////////////////////////////////////////////////
// NAME  
//            skip_decoding_datablock
//
// DESCRIPTION
//            uncompresses an image via GIF-coding
//
// INPUTS   
//            image - the address of a structure of type Image
//            opacity - The colormap index associated with the transparent color
//            func - callback function to determine if we need to continue
//
// OUTPUTS  
//            none        
//
// RETURN VALUE
//          returns True if all the pixels are uncompressed without error, 
//            otherwise False.
//           
/////////////////////////////////////////////////////////////////////////////
unsigned int skip_decoding_datablock
(
    Image           *image
)
{

    unsigned char            data_size;
    unsigned char            *tp;
    unsigned char            **pp;
    unsigned int             count;

    pp = &tp;  

    /*
    Initialize GIF data stream decoder.
    */
    data_size = myReadBlobByte(image);
    if (data_size > 8)
    {
        return OP_FALSE;
    }

    /*
    Read a new data block.
    */
    for ( ; ; )
    {
        count = myReadBlobBlock(image,pp);
        if (count == 0)
        {
            image->blob->offset -= 1;
            break;
        }
    }
    return(OP_TRUE);
}

⌨️ 快捷键说明

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