S3C6410的JPEG解码(转载)

三星已经对JPEG解码做好了驱动,应用通过调用JPEG解码的API函数,从而调用JPEG驱动,驱动通过6410的内部硬件解码,将JPEG格式的数据解码成YUV格式的数据,然后将YUV格式转化成RGB,通过LCD显示出来。

     在三星提供的BSP包中,有文件S3C6410_WinCE6.0_WM6.0_JPEG_API.pdf,里面详细介绍了JPEG的使用方法。另外,三星还做了个JPEG的例子,在BSP包中路径为:E:/WINCE600/PLATFORM/SMDK6410/SAMPLES/JPEG,直接在PB6.0中编译生成*.exe文件,即可在6410的平台上运行。

     JPEG的解码测试代码如下:

 

  1. void TestDecoder()  
  2.  
  3.     char *InBuf NULL;  
  4.     char *OutBuf NULL;  
  5.     char *OutPhyBuf NULL;  
  6.     char *OutRGBBuf NULL;  
  7.     char *OutRGBPhyBuf NULL;  
  8.     FILE *fp;  
  9.     FILE *CTRfp;  
  10.     UINT32 fileSize;  
  11.     UINT32 streamSize;  
  12.     void *handle;  
  13.     INT32 width, height, samplemode;  
  14.     JPEG_ERRORTYPE ret;  
  15.     char outFilename[128];  
  16.     char inFilename[128];  
  17.     BOOL result TRUE;  
  18. //  int i;//added by lqm.   
  19. #if (FPS == 1)   
  20.     INT32    decodeTime;  
  21. #endif   
  22.     DWORD    startTime;  
  23.     RETAILMSG(1,(L"------------------------Decoder Test Start ---------------------/n"));  
  24.     //   
  25.     // 0. Get input/output file name                            //   
  26.     //   
  27.     //CTRfp fopen(CTRL_FILE_NAME, "rb");// 解码时,CTRL_FILE_NAME "fname_dec.txt"   
  28.     CTRfp fopen("//Nand-disk//JPEG//fname_dec.txt", "rb");  
  29.     if(CTRfp == NULL)  
  30.      
  31.         RETAILMSG(1,(L"file open error %s/n", CTRL_FILE_NAME));  
  32.         return;  
  33.      
  34.     do  
  35.      
  36.         memset(outFilename, 0x00, sizeof(outFilename));// 将数组里面的128个数据全部填0   
  37.         memset(inFilename, 0x00, sizeof(inFilename));  
  38.         fscanf(CTRfp, "%s", inFilename);//将*CTRfp指向的文件CTRL_FILE_NAME里的第n行数据读到inFilename[]数组   
  39.         if(inFilename[0] == '#')//文件以"#"表示结束,当读到"#"时表示解码结束   
  40.          
  41.             RETAILMSG(1,(L"------------------------Decoder Test Done ---------------------/n"));  
  42.             fclose(CTRfp);  
  43.             return;  
  44.          
  45.         fscanf(CTRfp, "%s", outFilename);//将*CTRfp指向的文件CTRL_FILE_NAME里的第n+1行数据读到outFilename[]数组   
  46.         if(inFilename == NULL || outFilename == NULL)  
  47.          
  48.             RETAILMSG(1,(L"read file error/n"));  
  49.             RETAILMSG(1,(L"------------------------Decoder Test Done ---------------------/n"));  
  50.             fclose(CTRfp);  
  51.             return;  
  52.          
  53.         // 为什么下面的打印信息是隔一个字符打印一个?   
  54.         RETAILMSG(1,(L"inFilename %s /noutFilename %s/n", inFilename, outFilename));  
  55.         //   
  56.         // 1. handle Init                                           //   
  57.         //   
  58. #if (FPS == 1)   
  59.         decodeTime GetTickCount();//读取以毫秒为单位的计算机启动后经历的时间间隔。   
  60. #endif   
  61.         handle SsbSipJPEGDecodeInit();  
  62. #if (FPS == 1)           
  63.         decodeTime GetTickCount() decodeTime;  
  64.         RETAILMSG(1,(L"Initialization Time %d /n", decodeTime));  
  65. #endif   
  66.         if(handle == NULL)  
  67.          
  68.             RETAILMSG(1,(L"Decoder Init failed/n"));  
  69.             break;  
  70.          
  71.         //   
  72.         // 2. open JPEG file to decode                              //   
  73.         //   
  74.         fp fopen(inFilename, "rb");// 打开inFilename数组中指定的文件   
  75.         if(fp == NULL)  
  76.          
  77.             result FALSE;  
  78.             RETAILMSG(1,(L"file open error %s/n", inFilename));  
  79.             break;  
  80.          
  81.         // 以下三句用于计算文件的长度   
  82.         // 在这里用于计算打开的JTAG图像文件的大小(byte)   
  83.         fseek(fp, 0, SEEK_END);//把文件指针指向文件尾部   
  84.         fileSize ftell(fp);//读取当前指针位置偏离文件头部的字节数   
  85.         fseek(fp, 0, SEEK_SET);//把文件指针指向文件首部   
  86.         RETAILMSG(1,(L"filesize %d/n", fileSize));  
  87.         //   
  88.         // 3. get Input buffer address                              //   
  89.         //   
  90.         InBuf SsbSipJPEGGetDecodeInBuf(handle, fileSize);  
  91.         if(InBuf == NULL){  
  92.             RETAILMSG(1,(L"Input buffer is NULL/n"));  
  93.             result FALSE;  
  94.             break;  
  95.          
  96.         RETAILMSG(1,(L"inBuf 0x%x/n", InBuf));  
  97.         //   
  98.         // 4. put JPEG frame to Input buffer                        //   
  99.         //   
  100.         fread(InBuf, 1, fileSize, fp);//把fp指向的图像文件的数据存入输入缓冲区   
  101.         fclose(fp);//释放打开的图像文件   
  102.   
  103.         //   
  104.         // 5. Decode JPEG frame                                     //   
  105.         //   
  106. #if (FPS == 1)   
  107.         decodeTime GetTickCount();  
  108. #endif   
  109.         ret SsbSipJPEGDecodeExe(handle);//JPEG格式解码   
  110. #if (FPS == 1)           
  111.             decodeTime GetTickCount() decodeTime;  
  112.             RETAILMSG(1,(L"decodeTime %d ms/n", decodeTime));//打印解码所花的时间   
  113. #endif   
  114.         if(ret != JPEG_OK){  
  115.             RETAILMSG(1,(L"Decoding failed/n"));  
  116.             result FALSE;  
  117.             break;  
  118.          
  119.         //   
  120.         // 6. get Output buffer address                             //   
  121.         //   
  122.         OutBuf SsbSipJPEGGetDecodeOutBuf(handle, &streamSize);  
  123.         if(OutBuf == NULL){  
  124.             RETAILMSG(1,(L"Output buffer is NULL/n"));  
  125.             result FALSE;  
  126.             break;  
  127.          
  128.         printD("OutBuf 0x%x streamsize %d/n", OutBuf, streamSize);  
  129.         //   
  130.         // 7. get decode config.                                    //   
  131.         //   
  132.         SsbSipJPEGGetConfig(JPEG_GET_DECODE_WIDTH, &width);  
  133.         SsbSipJPEGGetConfig(JPEG_GET_DECODE_HEIGHT, &height);  
  134.         SsbSipJPEGGetConfig(JPEG_GET_SAMPING_MODE, &samplemode);  
  135.         RETAILMSG(1,(L"width %d height %d samplemode %d/n/n", width, height, samplemode));  
  136.         //   
  137.         // 8. write output file                                     //   
  138.         //   
  139. #if (TEST_DECODE_OUTPUT_YCBYCR == 1)   
  140.         DecodeFileOutYCBYCR(OutBuf, streamSize, outFilename);    // YCBYCR interleaved   
  141. #elif (TEST_DECODE_OUTPUT_YUV422 == 1)   
  142.         DecodeFileOutYUV422(OutBuf, streamSize, outFilename);    // yuv422 non-interleaved   
  143. #elif (TEST_DECODE_OUTPUT_RGB16 == 1)                            //RGB16   
  144.         OutPhyBuf SsbSipJPEGGetDecodeOutPhyBuf(handle);  
  145.         OutRGBPhyBuf SsbSipJPEGGetRGBPhyBuf(handle, LCD_X, LCD_Y);  
  146.         if(ConvertYCBYCRToRGB((int)OutPhyBuf, width, height,   
  147.                               POST_SRC_YUV422_CRYCBY,  
  148.                               (int)OutRGBPhyBuf, LCD_X, LCD_Y,  
  149.                               POST_DST_RGB16) == FALSE){  
  150.             RETAILMSG(1,(L"ConvertYCBYCRToRGB error/n"));  
  151.             result FALSE;  
  152.             break;  
  153.          
  154.         OutRGBBuf SsbSipJPEGGetRGBBuf(handle, LCD_X, LCD_Y);  
  155.         DecodeFileOutRGB16ToPPM(OutRGBBuf, LCD_X, LCD_Y, outFilename);   
  156. #elif(TEST_DECODE_OUTPUT_LCD == 1)   
  157.         OutPhyBuf SsbSipJPEGGetDecodeOutPhyBuf(handle);//获得解码输出缓冲的物理地址   
  158.         OutRGBPhyBuf SsbSipJPEGGetRGBPhyBuf(handle, LCD_X, LCD_Y);//获得解码输出缓冲的物理地址   
  159.         startTime GetTickCount();  
  160.         if(ConvertYCBYCRToRGB((int)OutPhyBuf, width, height,   
  161.                               POST_SRC_YUV422_CRYCBY,  
  162.                               (int)OutRGBPhyBuf, LCD_X, LCD_Y,  
  163.                               POST_DST_RGB16) == FALSE){  
  164.             RETAILMSG(1,(L"ConvertYCBYCRToRGB error/n"));  
  165.             result FALSE;  
  166.             break;  
  167.          
  168.         RETAILMSG(1,(L"converting time %d/n/n", GetTickCount() startTime));  
  169.         RETAILMSG(1,(L"/n/n This image will be disappeared after %d seconds....../n/n", DISPLAY_TIME));  
  170.         DisplayJPEG((int)OutRGBPhyBuf, LCD_X, LCD_Y, LCD_X, LCD_Y, DISPLAY_TIME);  
  171. #endif   
  172.         //   
  173.         // 9. finalize handle                                      //   
  174.         //   
  175.         SsbSipJPEGDecodeDeInit(handle);  
  176.         Sleep(5);  
  177.      
  178.     while(1);  
  179.     if(result == FALSE)  
  180.      
  181.         SsbSipJPEGDecodeDeInit(handle);  
  182.      
  183.     fclose(CTRfp);  
  184.     RETAILMSG(1,(L"------------------------Decoder Test Done ---------------------/n"));  
  185.  

    这些代码会调用JPGApi.c中的若干API函数,在API函数中可以看到他们开始打开驱动,然后逐个调用JPEG驱动了。例如,解码JPEG的函数如下:

 

  1. JPEG_ERRORTYPE SsbSipJPEGDecodeExe(void *openHandle)  
  2.  
  3.     int    ret;  
  4.     printD("API :: jCtx->decParam->fileSize %d/n", jCtx->decParam->fileSize);  
  5.     if(jCtx->decParam->decType == JPG_MAIN){  
  6.         ret DeviceIoControl(openHandle, IOCTL_JPG_DECODE, NULL,   
  7.                             0, NULL, 0,   
  8.                             (PDWORD)jCtx->decParam, NULL);  
  9.         if(ret == 0){  
  10.             RETAILMSG(1, (TEXT("API :: IOCTL_JPG_DECODE failed/r/n")));  
  11.             return JPEG_FAIL;  
  12.          
  13.         printD("API :: decParam->width %d decParam->height %d/n", jCtx->decParam->width, jCtx->decParam->height);  
  14.         printD("API :: streamSize %d/n", jCtx->decParam->dataSize);  
  15.      
  16.     else{  
  17.         // thumbnail decode, for the future work.   
  18.      
  19.     return JPEG_OK;  
  20.  

    驱动三星也已经都做好了,这里就不一一把代码贴上来了。

 

    值得注意的是,将该例子生成的可执行文件拷到WINCE平台运行的同时,还要将测试图片,记录测试图片路径的文本文件一并拷到WINCE平台,注意拷备的最终路径,要和程序中代码严格对应,否则无法打开图片文件或是文本文件。

    存放的图片路径如下:

    E:/WINCE600/PLATFORM/SMDK6410/SAMPLES/JPEG/test/testVectors

    存放的广本文件的路径如下:

    E:/WINCE600/PLATFORM/SMDK6410/SAMPLES/JPEG/test/fname_dec.txt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值