抽象
在为IPK存档(NDS Homebrew Image Viewer)编写解包器的过程中,我遇到了必须解码单个MCU的问题。原始源代码表示DCT的使用,但参考实现全部在ARM程序集中......
我目前正在为NDS Homebrew" Image Viewer"所使用的文件编写一个基本的解包器。 (http://gamebrew.org/wiki/Image_Viewer)。 原始网站似乎已关闭,但我在gamebrew上托管的档案中找到了源代码(包括文件格式说明)。
解包器由于方便(BinaryReader)而用C#编写,也因为它不需要快速。
我已经设法提取缩略图。它们存储为放气(zlib)BGR-Bitmaps。
全尺寸图像被分成MCU(8x8样本)。每个MCU也以放气形式存储。 到目前为止,我得到的解压缩数据看起来像DCTed数据。它看起来也像他们已经多路复用了#34;各个频道(这是4:1:1?)。
在NDS版本中,字节数据随后与量化表(64个有符号16位整数的数组)一起传递到一个函数中,如下所示:
void customjpeg_DecodeYUV411(s32 *pQuantizeTable,u8 *pData,u16 *pBuf)
{
pDCs=(s16*)pData;
pACs=(s8*)&pDCs[4*4*6];
static __attribute__ ((section (".dtcm"))) DCTELEM _y0[DCTSIZE2],_y1[DCTSIZE2],_y2[DCTSIZE2],_y3[DCTSIZE2],_cb[DCTSIZE2],_cr[DCTSIZE2];
TYUV411toRGB15_Data YUV411toRGB15_Data[4]={
{ NULL, _y0, &_cb[((4*0)*DCTSIZE)+(4*0)], &_cr[((4*0)*DCTSIZE)+(4*0)] },
{ NULL, _y1, &_cb[((4*0)*DCTSIZE)+(4*1)], &_cr[((4*0)*DCTSIZE)+(4*1)] },
{ NULL, _y2, &_cb[((4*1)*DCTSIZE)+(4*0)], &_cr[((4*1)*DCTSIZE)+(4*0)] },
{ NULL, _y3, &_cb[((4*1)*DCTSIZE)+(4*1)], &_cr[((4*1)*DCTSIZE)+(4*1)] },
};
// PrfStart();
// 3.759ms
for(u32 y=0;y<4;y++){
YUV411toRGB15_Data[0]._pBuf=&pBuf[((8*0)*64)+(8*0)];
YUV411toRGB15_Data[1]._pBuf=&pBuf[((8*0)*64)+(8*1)];
YUV411toRGB15_Data[2]._pBuf=&pBuf[((8*1)*64)+(8*0)];
YUV411toRGB15_Data[3]._pBuf=&pBuf[((8*1)*64)+(8*1)];
for(u32 x=0;x<4;x++){
DCT13bit_asm(pQuantizeTable,_y0);
DCT13bit_asm(pQuantizeTable,_y1);
DCT13bit_asm(pQuantizeTable,_y2);
DCT13bit_asm(pQuantizeTable,_y3);
DCT13bit_asm(pQuantizeTable,_cb);
DCT13bit_asm(pQuantizeTable,_cr);
YUV411_13bit_toRGB15_asm(YUV411toRGB15_Data);
YUV411toRGB15_Data[0]._pBuf+=DCTSIZE*2;
YUV411toRGB15_Data[1]._pBuf+=DCTSIZE*2;
YUV411toRGB15_Data[2]._pBuf+=DCTSIZE*2;
YUV411toRGB15_Data[3]._pBuf+=DCTSIZE*2;
}
pBuf+=(DCTSIZE*2)*64;
}
// PrfEnd(0); ShowLogHalt();
}
(取自:customjpeg.cpp)
我已经检查了一些在线资源,但他们似乎只关注编码过程。 不幸的是,我缺乏数学背景,因此我没有理解DCT的完整概念,因此逆转过程并不像我那样直接。
我花了一整天时间通过利用库和C#-DCT实现来实现这一目标,但我没有成功。