デコード

デコード

圧縮された画像データは下記のように解凍します。

UINT32 nWidth, nHeight, nLineBytes;
USHORT q[PUC_Q_COUNT];
UINT8* pDecodeBuf;

result = PUC_GetResolution(hDevice, &nWidth, &nHeight);
if (PUC_CHK_FAILED(result))
{
    return;
}

for (UINT32 i = 0; i < PUC_Q_COUNT; i++)
{
    result = PUC_GetQuantization(hDevice, i, &q[i]);
    if (PUC_CHK_FAILED(result))
    {
        return;
    }
}

nLineBytes = nWidth % 4 == 0 ? nWidth : nWidth + (4 - nWidth % 4);
pDecodeBuf = new UINT8[nLineBytes * nHeight];

result = PUC_DecodeData(pDecodeBuf, 0, 0, nWidth, nHeight, nLineBytes, xferData.pData, q);
if (PUC_CHK_FAILED(result))
{
    return;
}

デコードした画像は下記のようにビットマップとして保存できます。

UINT32 nInfoBytes;
BITMAPINFO* pBitmapInfo;
DWORD nPixelBytes;
BITMAPFILEHEADER fileHeader;
FILE* fp;

nInfoBytes = sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * 256);
pBitmapInfo = (BITMAPINFO*)new BYTE[nInfoBytes];
nPixelBytes = nLineBytes * nHeight;

memset(pBitmapInfo, 0, nInfoBytes);
pBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pBitmapInfo->bmiHeader.biWidth = nWidth;
pBitmapInfo->bmiHeader.biHeight = -(INT32)nHeight;
pBitmapInfo->bmiHeader.biPlanes = 1;
pBitmapInfo->bmiHeader.biBitCount = 8;
pBitmapInfo->bmiHeader.biCompression = BI_RGB;
pBitmapInfo->bmiHeader.biSizeImage = nPixelBytes;
pBitmapInfo->bmiHeader.biClrUsed = 256;

for (int i = 0; i < 256; i++)
{
    pBitmapInfo->bmiColors[i].rgbRed = (BYTE)i;
    pBitmapInfo->bmiColors[i].rgbGreen = (BYTE)i;
    pBitmapInfo->bmiColors[i].rgbBlue = (BYTE)i;
}

memset(&fileHeader, 0, sizeof(fileHeader));
fileHeader.bfType = ('M' << 8) + 'B';
fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + nInfoBytes + nPixelBytes;
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + nInfoBytes;

_tfopen_s(&fp, _T("test.bmp"), _T("wb"));
fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
fwrite(pBitmapInfo, nInfoBytes, 1, fp);
fwrite(pDecodeBuf, nPixelBytes, 1, fp);
fclose(fp);

delete[] pBitmapInfo;

注釈

  • 画素はトップダウンで並んでいるため、 BITMAPINFOHEADER の高さはマイナスを指定しています。

  • 画像の横幅は4の倍数で確保されている必要があります。

DC成分のみをデコード

圧縮された画像データのDC成分のみをデコードするには下記のようにおこないます。

UINT32 nBlockCountX, nBlockCountY, nLineBytes;
UINT8* pDecodeDCBuf;
nLineBytes = nWidth % 4 == 0 ? nWidth : nWidth + (4 - nWidth % 4);
nBlockCountX = nLineBytes % 8 == 0 ? nLineBytes / 8 : (nLineBytes + 7) / 8;
nBlockCountY = nHeight % 8 == 0 ? nHeight / 8 : (nHeight + 7) / 8;

pDecodeDCBuf = new UINT8[nBlockCountX * nBlockCountY];

result = PUC_DecodeDCData(pDecodeDCBuf, 0, 0, nBlockCountX, nBlockCountY, xferData.pData);
if (PUC_CHK_FAILED(result))
{
    return;
}