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

📄 jpegdecoder.c

📁 jpeg图像文件软件解码器的arm版本的源代码程序
💻 C
📖 第 1 页 / 共 2 页
字号:
            return JPEG_ERR_FATAL;
        }
    }

    return JPEG_OK;
}


/////////////////////////////////////////////////////////////////////////////
// NAME  
//            JPEGDecodeFrame
//
// DESCRIPTION
//           This function is called to decode one JPEG frame. This function can 
//           decode a standard JPEG frame.
//
// INPUTS   
//            jpegDecoder - pointer to JPEGDecoder structure
//            findJPEGSaveMCU - function pointer for storing MCU to image buffer
//            func - callback function to determine if we should continue
//            frmBufSize - size of frame buffer
//            numBits - number of bits per pixel
//            sizex - width of output image
//            sizey - height of output image
//            jpegFrmBuf - pointer to JPEG frame buffer
//            decodedFormat - output image format
//            decodedFrmBuf - pointer to decoded frame buffer
//            xDst - x location of image in output buffer
//            yDst - y location of image in output buffer
// 
// OUTPUTS  
//            decodedFrmBuf - stores output image in this buffer        
//
// RETURN VALUE
//          Returns JPEG_OK if successful, returns an error code otherwise.    
//           
/////////////////////////////////////////////////////////////////////////////
int JPEGDecodeFrame
(
    JPEGDecoder         *jpegDecoder, 
    FindJPEGSaveMCU     findJPEGSaveMCU, 
    OP_BOOLEAN          func(OP_UINT16 x, OP_UINT16 y),
    int                 frmBufSize, 
    int                 numBits, 
    int                 sizex, 
    int                 sizey, 
    void                *jpegFrmBuf, 
    int                 decodedFormat, 
    void                *decodedFrmBuf,
    int                 xDst, 
    int                 yDst
)
{
    int             errCode;
    int             firstFieldIdx;
    /* int secondFieldIdx; */

    ByteBuffer      byteBuffer;
    OP_UINT8        *frameBuffer;

    // use a ByteBuffer structure to control the input
    byteBuffer.dataBuf   = (OP_UINT8 *) jpegFrmBuf;
    byteBuffer.bufLength = frmBufSize;
    byteBuffer.bufPtr    = 0;

    errCode = JPEGSegmentsConfig(&byteBuffer, &jpegDecoder->jpegSegments, &firstFieldIdx, 
                                 jpegDecoder->AllocateMemory, jpegDecoder->Deallocate);

    if (errCode != JPEG_OK)
    {
        return errCode;
    }

    errCode = FirstFrameInitialize(jpegDecoder, decodedFormat, numBits, sizex, sizey, 
                                   (firstFieldIdx != 0));

    if (errCode != JPEG_OK)
    {
        return errCode;
    }

    frameBuffer = decodedFrmBuf;

    JPEGFieldDecInitialize(&jpegDecoder->decodedImage, firstFieldIdx, frameBuffer, xDst, yDst);

    jpegDecoder->SaveMCUFunction = findJPEGSaveMCU(&jpegDecoder->decodedImage);

    errCode = JPEGFieldDecode(&byteBuffer, jpegDecoder, func);

/*    if ((firstFieldIdx != 0) && (errCode == JPEG_OK))
    {
        // we need to decode the other field
        // the other field data is complete, decode the other field
        errCode = JPEGSegmentsConfig
            (&byteBuffer, jpegDecoder.jpegSegments, &secondFieldIdx);
        
        // we have only one field in the frame
        if (secondFieldIdx == firstFieldIdx)
            errCode = JPEG_WARN_ONE_FIELD;
        
        if (errCode == JPEG_OK)
        {
            // check the image size to see if it is supported
            JPEGFrameHeader *frameHeader = 
                &(jpegDecoder.jpegSegments->frameHeader);
            
            JPEGFieldDecInitialize
                    (jpegDecoder.decodedImage, secondFieldIdx, frameBuffer, xDst, yDst);
                
            errCode = JPEGFieldDecode(&byteBuffer, jpegDecoder);
        }
        else
        {
            // decode the first filed again
            byteBuffer.dataBuf   = (OP_UINT8 *) jpegFrmBuf;
            byteBuffer.bufLength = frmBufSize;
            byteBuffer.bufPtr    = 0;

            // we need to decode the other field
            // the other field data is complete, decode the other field
            errCode = JPEGSegmentsConfig
                (&byteBuffer, jpegDecoder.jpegSegments, &secondFieldIdx);

            // stored in the other field
            if (secondFieldIdx == 1)
                secondFieldIdx = 2;
            else
                secondFieldIdx = 1;

            JPEGFieldDecInitialize
                (jpegDecoder.decodedImage, secondFieldIdx, frameBuffer, xDst, yDst);
                
            errCode = JPEGFieldDecode(&byteBuffer, jpegDecoder);
        }
    }      */
    
    return errCode;
}

/////////////////////////////////////////////////////////////////////////////
// NAME  
//            JPEGGetJPEGFrameSize
//
// DESCRIPTION
//           Get the size of the frame size of the JPEG image. It also performs
//           some basic format checking.
//
// INPUTS   
//            jpegBuf  - pointer to input bitstream
//            frameWidth - pointer to frame width
//            frameHeight - pointer to frame height
// 
// OUTPUTS  
//            frameWidth - returns frame width
//            frameHeight - returns frame height
//
// RETURN VALUE
//          Returns 0 if successful, returns a nonzero value otherwise.    
//           
/////////////////////////////////////////////////////////////////////////////
int JPEGGetJPEGFrameSize
(
    OP_UINT8       *jpegBuf, 
    OP_UINT16      *frameWidth, 
    OP_UINT16      *frameHeight
)
{
    OP_UINT8        ch1;
    OP_UINT8        ch2;
    OP_UINT32       ind;

    ind = 0;
    // check the first marker to make sure this is an JPEG image
    ch1 = jpegBuf[ind++];
    ch2 = jpegBuf[ind++];
    if ((ch1 != 0xFF) || (ch2 != JPEG_MARKER_SOI))
    {
        return 1;
    }

    // search for SOF marker, may not be very reliable!
    ch2 = 0;
    while (ch2 != JPEG_MARKER_SOF0)
    {
        ch1 = 0;
        while (ch1 != 0xFF)
        {
            ch1 = jpegBuf[ind++];
        }

        ch2 = jpegBuf[ind++];

        if (ch2 == JPEG_MARKER_SOF0)
        {
            int segmentLength = (jpegBuf[ind++] << 8);
            segmentLength = segmentLength + jpegBuf[ind++];
            
            // either can not handle more than 3 components, or find a 
            // JPEG_SOF_MARKER by mistake, continue searching
            if (segmentLength != 17)
            {
                ch2 = 0;
            }
            else
            {
                // read the frameWidth and frameHeight
                int precision = jpegBuf[ind++];

                if (precision != 8)
                {
                    return 1;        // could not handle this
                }

                *frameHeight = ((OP_UINT16)jpegBuf[ind++] << 8); 
                *frameHeight = *frameHeight + jpegBuf[ind++];
                *frameWidth  = ((OP_UINT16)jpegBuf[ind++] << 8); 
                *frameWidth  = *frameWidth + jpegBuf[ind++];
            }
        }
        else
        {
            if ((ch2 > JPEG_MARKER_SOF0) && (ch2 <= JPEG_MARKER_SOF15) && (ch2 != JPEG_MARKER_DHT))
            {
                return 1;
            }

            if (ch2 != JPEG_MARKER_SOI)
            {
                // only SOI does not define a segment
                int segmentLength = jpegBuf[ind++] << 8;
                segmentLength = segmentLength + jpegBuf[ind++];
                
                ind = ind + segmentLength - 2;
            }
        }
    }

    return 0;
}


/////////////////////////////////////////////////////////////////////////////
// NAME  
//            JPEGGetThumbnailInfo
//
// DESCRIPTION
//           Get information about the thumbnail image
//             (size, type, data)
//
// INPUTS   
//            jpegBuf  - pointer to input bitstream
//            info - pointer to thumbnail info structure
// 
// OUTPUTS  
//            info - returns thumbnaiil info
//
// RETURN VALUE
//          Returns 0 if successful, returns a nonzero value otherwise.    
//           
/////////////////////////////////////////////////////////////////////////////
int JPEGGetThumbnailInfo
(
    OP_UINT8        *jpegBuf, 
    ThumbnailInfo   *info
)
{
    OP_UINT8        ch1; 
    OP_UINT8        ch2;
    OP_UINT16       flag;
    OP_UINT32       ind;

    flag = 1;

    ind = 0;
    // check the first marker to make sure this is an JPEG image
    ch1 = jpegBuf[ind++];
    ch2 = jpegBuf[ind++];
    if ((ch1 != 0xFF) || (ch2 != JPEG_MARKER_SOI))
    {
        return flag;
    }

    // search for APP0 marker, may not be very reliable!
    ch2 = 0;
    while (ch2 != JPEG_MARKER_APP0)
    {
        ch1 = 0;
        while (ch1 != 0xFF)
        {
            ch1 = jpegBuf[ind++];
        }

        ch2 = jpegBuf[ind++];

        if (ch2 == JPEG_MARKER_APP0)
        {
            int segmentLength = (jpegBuf[ind++] << 8);
            segmentLength += jpegBuf[ind++];
            
            // check if JFIF extension
            if(jpegBuf[ind] == 'J' && jpegBuf[ind + 1] == 'F' &&
                    jpegBuf[ind + 2] == 'I' && jpegBuf[ind + 3] == 'F')
            {
                flag = 0;

                // get thumbnail size
                info->thumbnailWidth = (OP_UINT16)jpegBuf[ind + 12];
                info->thumbnailHeight = (OP_UINT16)jpegBuf[ind + 13];
                info->thumbnailType = THUMBNAIL_RGB;
                info->thumbnailData = (OP_UINT8 *)(&(jpegBuf[14]));
            }
            // check if JFXX extension
            else if(jpegBuf[ind] == 'J' && jpegBuf[ind + 1] == 'F' &&
                    jpegBuf[ind + 2] == 'X' && jpegBuf[ind + 3] == 'X')
            {
                flag = 0;

                // get thumbnail size
                if(jpegBuf[ind + 5] == 0x10)
                {
                    info->thumbnailType = THUMBNAIL_JPEG;
                    info->thumbnailData = (OP_UINT8 *)(&(jpegBuf[6]));
                    if(JPEGGetJPEGFrameSize(info->thumbnailData, 
                            &info->thumbnailWidth, &info->thumbnailHeight))
                    {
                        flag = 1;
                    }
                }
                else if(jpegBuf[ind + 5] == 0x11)
                {
                    info->thumbnailType = THUMBNAIL_INDEX;
                    info->thumbnailData = (OP_UINT8 *)(&(jpegBuf[8]));
                    info->thumbnailWidth = (OP_UINT16)jpegBuf[ind + 6];
                    info->thumbnailHeight = (OP_UINT16)jpegBuf[ind + 7];
                }
                else if(jpegBuf[ind + 5] == 0x13)
                {
                    info->thumbnailType = THUMBNAIL_RGB;
                    info->thumbnailData = (OP_UINT8 *)(&(jpegBuf[8]));
                    info->thumbnailWidth = (OP_UINT16)jpegBuf[ind + 6];
                    info->thumbnailHeight = (OP_UINT16)jpegBuf[ind + 7];
                }
            }
         
            ind += segmentLength - 2;
        }
        else
        {
            if ((ch2 > JPEG_MARKER_SOF0) && (ch2 <= JPEG_MARKER_SOF15) && (ch2 != JPEG_MARKER_DHT))
            {
                break;
            }

            if (ch2 != JPEG_MARKER_SOI)
            {
                // only SOI does not define a segment
                int segmentLength = jpegBuf[ind++] << 8;
                segmentLength += jpegBuf[ind++];
                
                ind += segmentLength - 2;
            }
        }
    }

    if(info->thumbnailWidth == 0 && info->thumbnailHeight == 0) 
    {
        flag = 1;
    }
    return flag;
}


/////////////////////////////////////////////////////////////////////////////
// NAME  
//            JPEGDecodeThumbnail
//
// DESCRIPTION
//           Decode the thumbnail image (RGB or index type)
//             And save the output in the modified RGB32 format
//
// INPUTS   
//            info - pointer to thumbnail info structure
//            outbuf - pointer to output image buffer
// 
// OUTPUTS  
//            outbuf - returns output image
//
// RETURN VALUE
//          Returns 0 if successful, returns a nonzero value otherwise.    
//           
/////////////////////////////////////////////////////////////////////////////
int JPEGDecodeThumbnail
(
    ThumbnailInfo       *info, 
    JPEGOutputType      *outbuf
)
{
    OP_UINT8    *inptr;
    OP_UINT16   i; 
    OP_UINT16   numpixels;

    // compute the number of pixels in thumbnail
    numpixels = info->thumbnailWidth * info->thumbnailHeight;

    // set input pointer
    inptr = info->thumbnailData;

    // check thumbnail type
    if(info->thumbnailType == THUMBNAIL_RGB)
    {
        OP_UINT8 *outptr;

        // set output pointer
        outptr = (OP_UINT8 *)outbuf;
        
        // decode the thumbnail
        for(i = 0; i < numpixels; i++)
        {
            *outptr++ = *inptr++;             
            *outptr++ = *inptr++;             
            *outptr++ = *inptr++;             
            *outptr++ = DEFAULT_ALPHA_VALUE;
        }
    }             
    else if(info->thumbnailType == THUMBNAIL_INDEX)
    {
        JPEGOutputType colortable[256];
        JPEGOutputType *outptr;

        // set output pointer
        outptr = outbuf;

        // get color table
        for(i = 0; i < 256; i++)
        {
            colortable[i].red = *inptr++;             
            colortable[i].green = *inptr++;             
            colortable[i].blue = *inptr++;             
            colortable[i].alpha = DEFAULT_ALPHA_VALUE;
        }

        // then decode the thumbnail
        for(i = 0; i < numpixels; i++)
        {
            *outptr++ = colortable[*inptr++];
        }
    }
    else
    {
        return 1;
    }

    return 0;
}
        

⌨️ 快捷键说明

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