TJpgDec—轻量级JPEG解码器

TJpgDec—轻量级JPEG解码器

本文由乌合之众lym瞎编,欢迎转载blog.cnblogs.net/oloroso
下文中解码一词皆由decompression/decompress翻译而来。

TJpgDec是一个为小型嵌入式系统高度优化的创建JPEG图像的解码模块。它工作时占用的内存非常低,以便它可以集成到微控芯片,如AVR, 8051, PIC, Z80, Cortex-M0等。

特性

  • 平台独立。使用ANSI-C编写
  • 易于使用的主操作模式
  • 完全可重入的体系结构

    Very small memory footprint:

  • 非常小的内存占用

    独立于图像尺寸的3K工作内存。
    3.5-8.5KB的文本和常数ROM.

  • 输出格式:

    缩放比例:1/1、1/2、1/4或1/8可选。
    像素格式:RGB888或RGB565预配置。

API接口

有两个函数用于分析和解码JPEG图像。

jd_prepare

jd_prepare - 准备解码JPEG图像

jd_prepare分析JPEG数据并创建一个解码对象(decompression object)用于随后的解码过程。

JRESULT jd_prepare (
            JDEC* jdec,            /* Pointer to blank decompression object */
            UINT(*infunc)(JDEC*,BYTE*,UINT), /* Pointer to input function */
            void* work,            /* Pointer to work area */
            UINT sz_work,          /* Size of the work area */
            void* device           /* Device identifier for the session */
            );

参数

  • jdec

    指定解码对象去初始化。这个解码对象是用于后续的解码操作。

  • input

    指定用户定义的数据输入函数。jd_preparejd_decomp调用这个函数来从输入流读取JPEG数据.

  • work

    指向此会话工作区域的指针。它应该与word边界对齐或者它可以导致一个异常。

  • sz_work

    指定工作区域的字节数。TJpgDec至多需要3092字节的工作区域,这依赖于JPEG图像的内置参数表。通常情况下是3092字节工作区域.

  • device

    指定用户定义的会话设备标识。它保存在解码对象的device成员中。它可以用于I/O函数去识别当前会话。当I/O device固定在project或者不需要这个功能,设置为NULL并忽略它。

返回值

  • JDR_OK

    Function succeeded and decompression object is valid.
    函数执行成功,且编码对象是有效的。

  • JDR_INP

    An error occured in input function due to hard error or wrong stream termination.
    一个错误发生在input函数,由于硬件错误或者流终止。

  • JDR_MEM1

    Insufficient work area for this JPEG image.
    工作区域不足解码这个JPEG图像。

  • JDR_MEM2

    Insufficient input buffer for this JPEG image. JD_SZBUF may be too small.
    输入缓冲器不足读取这个JPEG图像,JD_SZBUF可能过小。

  • JDR_PAR

    Parameter error. Given pointer to the work area is NULL.
    参数错误。传入的工作区指针为NULL。

  • JDR_FMT1

    Data format error. The JPEG data can be collapted.
    数据格式错误。JPEG数据损坏。

  • JDR_FMT2

    Right format but not supported. May be a grayscale image.
    格式正确,但不支持。也许是一个灰度图像。

  • JDR_FMT3

    Not supported JPEG standard. May be a progressive JPEG image.
    不支持JPEG标准,也许是一个先进的JPEG图像。

描述

jd_prepare函数是JPEG解码会话的第一阶段。它分析JPEG图像和创建解码参数表。函数成功后,会话准备好在jd_decomp函数解码JPEG图像。应用程序可以参考JPEG解码对象中存储的尺寸大小。这个信息将用于在后续的解码阶段配置输出设备(device)和参数。

jd_decomp

jd_decomp - 执行解码JPEG图像

jd_decomp函数解码JPEG图像并输出RGB数据。

JRESULT jd_decomp (
            JDEC* jdec,             /* Pointer to valid decompressor object */
            UINT(*outfunc)(JDEC*,void*,JRECT*), /* Pointer to output function */
            BYTE scale              /* Scaling factor */
            );

参数

  • jdec

    指定有效的解码对象。

  • outfunc

    指定用户定义的输出函数。jd_decomp调用这个函数去输出解码JPEG图像的RGB形式。

  • scale

    指定输出比例因子N。输出图像的缩小比例为1/2^N(N = 0 to 3)。当缩放功能禁用时(JD_USE_SCALE == 0),它必须是0.

返回值

  • JDR_OK

    Function succeeded.
    函数执行成功。

  • JDR_INTR
    The decompression process is interrupted by output function.

    解码过程在输出函数中断。

  • JDR_INP

    An error occured in input function due to hard error or wrong stream termination.
    一个错误发生在input函数,由于硬件错误或者流终止。

  • JDR_PAR

    Parameter error. Given scale factor is invalid.
    参数错误。给定的缩放值无效。

  • JDR_FMT1

    Data format error. The JPEG data can be collapted.
    数据格式错误。JPEG数据损坏。

描述

jd_decomp是JPEG解码会话的第二阶段。它解码JPEG图像并通过用户定义的输出函数输出数据,在它之后,解码对象将不在有效。

在解码时指定的比例因子,它将JPEG图像按1/2、1/4或1/8比例缩放尺寸。例如,当解码一个1024x768大小JPEG图像在1/4比例,它将输出256x192大小。相比不缩放,1/2和1/4的缩放由于求均值,解码速度略有下降。但是1/8缩放相比不缩放是2-3倍的速度输出,因为每个块IDCT和求均值可以跳过。这一特点适合创建缩略图。

I/O函数

输入JPEG数据并输出解码后像素,TJpgDec需要用户定义两个I/O函数

Input Function

Input funciotn - 从输入流读取JPEG数据

用户定义的从输入流读取数据的输入函数。

UINT in_func (
            JDEC* jdec,    /* Pointer to the decompression object */
            BYTE* buff,    /* Pointer to buffer to store the read data */
            UINT ndata     /* Number of bytes to read */
            );

参数

  • jdec

    指定解码会话的解码对象。

  • buff

    指定读缓冲器去保存读取数据。传入NULL将数据从输入流移除。

  • ndata

    指定从输入流读取或移除的字节数。

返回值

返回读取或移除的字节数。若返回0,jd_preparejd_decomp函数将终止并返回JDR_INP

描述

这个函数是TJpgDec模块的数据输入接口。可以通过指向设备标识符的指针来标识相应的解码会话。

Output Function

Output function - 写像素数据到输出设备

用户定义的输出函数,写解码像素到输出设备。

UINT out_func (
            JDEC* jdec,    /* Pointer to the decompression object */
            void* bitmap,  /* RGB bitmap to be output */
            JRECT* rect    /* Rectangular region to output */
            );

参数

  • jdec

    指定会话的解码对象。

  • bitmap

    指定RGB位图(bitmap)用于输出。

  • rect

    指定在图像中的矩形区域去输出RGB位图。

返回值

通常返回1,以便TJpgDec继续解码过程。当它返回0,jd_decomp函数终止并返回JDR_INTR,这在中断减压过程中有用。

描述

这个函数是TJpgDec模块的数据输出函数。可以通过指向设备标识符的指针来标识相应的解码会话,jdec->device通过jd_prepare函数第五个参数确定。

在这个函数中,位图发送到帧缓冲或显示设备。第一个像素是位图矩形的左上角位置,最后一个像素是右下角位置。矩形的大小从1x116x16取决于图像的裁剪、缩放和采样因子。如果矩形是帧缓冲区,它将在函数中倍裁剪。
像素格式取决于JD_FORMAT参数的配置选项。当它配置为RGB888,位图是一个字节数组,每3个字节保存一个RGB像素:RRRRRRRR, GGGGGGGG, BBBBBBBB, RRRRRRRR, GGGGGGGG, BBBBBBBB, ...;配置为RGB565时,位图是一个WORD数组,RGB数据1word每像素:RRRRRGGGGGGBBBBB, RRRRRGGGGGGBBBBB, RRRRRGGGGGGBBBBB, ...

资源

TJpgDec是一个免费软件,对教育、研究和开发开发。你可以使用、修改和重新分发它,对个人项目或商业产品没有任何限制和责任。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#ifndef JPEGDECODE_H #define JPEGDECODE_H #include "global.h" #include "globalextern.h" typedef unsigned char BYTE; struct ImageComponentData { double value[3]; }; class MBitReader { public: BYTE* Data; int m_currentData; int m_currentDataIndex; int m_currentBitPosition; MBitReader(BYTE* data,int currentDataIndex) { Data=data; m_currentBitPosition=8; m_currentDataIndex=currentDataIndex; m_currentData=Data[m_currentDataIndex]; } public: int ReadNextBit() { if (m_currentBitPosition-1> m_currentBitPosition) & 0x01; } }; class MJpegDecode { public: struct _JFIFAPPOInfo { BYTE APP0[2]; /* 02h Application Use Marker */ BYTE Length[2]; /* 04h Length of APP0 Field */ BYTE Identifier[5]; /* 06h "JFIF" (zero terminated) Id String */ BYTE Version[2]; /* 0Bh JFIF Format Revision */ BYTE Units; /* 0Dh Units used for Resolution */ BYTE Xdensity[2]; /* 0Eh Horizontal Resolution */ BYTE Ydensity[2]; /* 10h Vertical Resolution */ BYTE XThumbnail; /* 12h Thumbnail Horizontal Pixel Count */ BYTE YThumbnail; /* 13h Thumbnail Vertical Pixel Count */ } JFIFAPPOINFO; struct _JFIFDQTInfo { BYTE DQT[2]; // 14h 量化表段标记 BYTE Length[2]; // 16h 量化表段长度 BYTE Identifier; // 18h 量化表ID BYTE QTData[64]; // 19h 量化表数据 } JFIFDQTINFO[2]; struct _JFIFSOFOInfo { BYTE SOFO[2]; // 9Eh 帧开始段标记 BYTE Length[2]; // A0h 帧开始段长度 BYTE BitCount; // A2h 样本精度bit位数 BYTE Height[2]; // A5h 图像像素宽度 BYTE Width[2]; // A3h 图像像素高度 BYTE ComponentsCount; // A7h 图像组件计数 BYTE YIdentifier; // A8h 亮度Y的ID号 BYTE YHVSamplingCoefficient; // A9h 亮度Y垂直和水平采样系数 BYTE YUsedDQTIdentifier; // AAh 亮度Y使用的量化表ID号 BYTE CbIdentifier; // ABh 色度Cb的ID号 BYTE CbHVSamplingCoefficient; // ACh 色度Cb垂直和水平采样系数 BYTE CbUsedDQTIdentifier; // ADh 色度Cb使用的量化表ID号 BYTE CrIdentifier; // AEh 色度Cr的ID号 BYTE CrHVSamplingCoefficient; // AFh 色度Cr垂直和水平采样系数 BYTE CrUsedDQTIdentifier; // B0h 色度Cr使用的量化表ID号 } JFIFSOFOINFO; struct _JFIFDRIInfo { BYTE DRI[2]; BYTE Length[2]; BYTE NMCUReset[2]; //每n个MCU块就有一个 RSTn 标记. } JFIFDRIINFO; struct _JFIFDHTInfo { BYTE DHT[2]; // B1h 哈夫曼表定义段标记 BYTE Length[2]; // B3h 哈夫曼表段长度 BYTE HTIdentifier; // B5h 哈夫曼表号 BYTE NBitsSymbolsCount[16]; // B6h (符号的二进制位长度为n)的符号个数 BYTE SymbolsTable[256]; // C6h 按递增次序代码长度排列的符号表 } JFIFDHTINFO[2][2]; struct _JFIFSOSInfo { BYTE SOS[2]; // 261h 扫描开始段标记 BYTE Length[2]; // 263h 扫描开始段长度 BYTE ComponentsCount; // 265h 扫描行内组件的数量 BYTE YIdentifier; // 266h 亮度Y的ID号 BYTE YHTTableID; // 267h 亮度Y使用的哈夫曼表ID号 BYTE CbIdentifier; // 268h 色度Cb的ID号 BYTE CbHTTableID; // 269h 色度Cb使用的哈夫曼表ID号 BYTE CrIdentifier; // 26Ah 色度Cr的ID号 BYTE CrHTTableID; // 26Bh 色度Cr使用的哈夫曼表ID号 BYTE Reserved[3]; // 26Ch 3个未知保留字节 } JFIFSOSINFO; private: struct HuffmanTable { int CodeOfFirstNLengthSymbol[17]; //长度为N的第一个码字的整数值 int NLengthToSymbolsTableIndex[16]; //查表得到第一个长度为N的符号位于符号表的索引 } HUFFMANTABLE[2][2]; public: int ReadJFIFInfo(const BYTE* const jfifData,int jfifDataSize); void DecodeData(int mcuStartIndex,BYTE* jfifData,int jfifDataSize,ImageComponentData*& targetBitmapData); void SetHuffmanTable(); void DecodeOneDUDC(MBitReader* myBitReader,double* DU,double& lastDC,int index1,int index2); void DecodeOneDUAC(MBitReader* myBitReader,double* DU,int index1,int index2); void DecodeOneMCU(MBitReader* myBitReader,int mcuXn,int mcuYn,int mcuWidth,int mcuHeight,double *DU,ImageComponentData* targetImage); void InverseQuantization(double* du,BYTE* quantizationTable); void InverseZigzag(double* sourceDU,double* targetDU); void IDCT(double* sourceDU,double* targetDU); void YCbCrToRGB(ImageComponentData* sourceImage,ImageComponentData* targetImage); public: int imageHeight; int imageWidth; int alignedImageWidth; int alignedImageHeight; HuffmanTable* HT; double DC[3]; int HSamplingCoefficient[3]; int VSamplingCoefficient[3]; int DQTID[3]; int nMCUReset; }; #endif // JPEGDECODE_H
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值