#include <windows.h> #include "JPEG2000.h" // Our simple examples functions : // Using IMJ2Dec (jp2_decode.cpp, jp2_decode_skip_level.cpp) extern int Decode(int nWidth, int nHeight, PBYTE pIn, int nIn, PBYTE pOut, int nOut, DWORD fccOut, int nOutBits); extern int DecodeSkip(int nInWidth, int nInHeight, PBYTE pIn, int nIn, int nInSkip, PBYTE pOut, int nOut, DWORD fccOut, int nOutBits); // Using IMJ2Enc (jp2_encode.cpp) extern int Encode(int nWidth, int nHeight, PBYTE pIn, int nIn, DWORD fccIn, int nInBits, PBYTE pOut, int nOut, int nQuality); // Using CMJ2DecMT (jp2_decodeMT.cpp) extern int Decode2Fields(int nWidth, int nHeight, PBYTE pIn1, int nIn1, PBYTE pIn2, int nIn2, PBYTE pOut, int nOut, DWORD fccOut, int nOutBits); extern int Decode2Frames(int nWidth, int nHeight, PBYTE pIn1, int nIn1, PBYTE pIn2, int nIn2, PBYTE pOut1, int nOut1, PBYTE pOut2, int nOut2, DWORD fccOut, int nOutBits); extern int DecodeST(int nWidth, int nHeight, PBYTE pIn, int nIn, PBYTE pOut, int nOut, DWORD fccOut, int nOutBits); // Using CMJ2EncMT (jp2_encodeMT.cpp) extern int Encode2Fields(int nWidth, int nHeight, PBYTE pIn, int nIn, DWORD fccIn, int nInBits, PBYTE pOut1, int &nOut1, PBYTE pOut2, int &nOut2, int nQuality); extern int Encode2Frames(int nWidth, int nHeight, PBYTE pIn1, int nIn1, PBYTE pIn2, int nIn2, DWORD fccIn, int nInBits, PBYTE pOut1, int &nOut1, PBYTE pOut2, int &nOut2, int nQuality); extern int EncodeST(int nWidth, int nHeight, PBYTE pIn, int nIn, DWORD fccIn, int nInBits, PBYTE pOut, int nOut, int nQuality); // Load a J2C file, alloc bits buffer, fill buffer, return size of buffer. DWORD LoadJ2C(PCHAR pszFileName, PBYTE *pp) { HANDLE hFile; DWORD dwSize = 0; DWORD dwBytesRed = 0; if (!pp || *pp) // *pp must be NULL {return 0;} hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); dwSize = GetFileSize(hFile, NULL); // Alloc J2C bits buffer, don't forget to free it !!! if (dwSize) { *pp = (PBYTE)malloc(dwSize); } ReadFile(hFile, *pp, dwSize, &dwBytesRed, NULL); CloseHandle(hFile); return dwBytesRed; } // Save a J2C file, return bytes written. DWORD SaveJ2C(PCHAR pszFileName, PBYTE p, DWORD dwSize) { HANDLE hFile; DWORD dwBytesWritten = 0; if (!p || !dwSize) {return 0;} hFile = CreateFile(pszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); WriteFile(hFile, p, dwSize, &dwBytesWritten, NULL); CloseHandle(hFile); return dwBytesWritten; } // Load a DIB file, alloc DIB bits buffer, fill buffer, return size of buffer. DWORD LoadDIB(PCHAR pszFileName, PBITMAPINFOHEADER pFmt, PBYTE *pp) { BITMAPFILEHEADER bmfHdr; // Header for Bitmap file HANDLE hFile; DWORD dwBytesRed; DWORD bitsXXX[3]; if (!pFmt || !pp || *pp) // *pp must be NULL {return 0;} hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); // Read the file header ReadFile(hFile, &bmfHdr, sizeof(BITMAPFILEHEADER), &dwBytesRed, NULL); // Read the DIB header and the bits ReadFile(hFile, &pFmt->biSize, sizeof(pFmt->biSize), &dwBytesRed, NULL); ReadFile(hFile, ((PBYTE)pFmt) + sizeof(pFmt->biSize), pFmt->biSize - sizeof(pFmt->biSize), &dwBytesRed, NULL); // Read RGBMASK if needed if (pFmt->biCompression == BI_BITFIELDS) { ReadFile(hFile, bitsXXX, 3 * sizeof(DWORD), &dwBytesRed, NULL); } // Read GRAYSCALE palette if needed if (pFmt->biBitCount == 8) { RGBQUAD pal[256]; ReadFile(hFile, pal, 256 * sizeof(RGBQUAD), &dwBytesRed, NULL); } // Alloc DIB bits buffer, don't forget to free it !!! if (pFmt->biSizeImage) { *pp = (PBYTE)malloc(pFmt->biSizeImage); } // Read the DIB bits dwBytesRed = 0; ReadFile(hFile, *pp, pFmt->biSizeImage, &dwBytesRed, NULL); CloseHandle(hFile); return dwBytesRed; } // Save a DIB file, return bytes written for DIB bits not for the whole file. DWORD SaveDIB(PCHAR pszFileName, PBITMAPINFOHEADER pFmt, PBYTE p) { BITMAPFILEHEADER bmfHdr; // Header for Bitmap file HANDLE hFile; DWORD dwBytesWritten; const DWORD bits565[] = {0x00F800,0x0007E0,0x00001F}; if (!pFmt || !p) {return 0;} hFile = CreateFile(pszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); bmfHdr.bfType = *((WORD*)"BM"); bmfHdr.bfSize = sizeof (BITMAPFILEHEADER) + pFmt->biSize + pFmt->biSizeImage; bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; bmfHdr.bfOffBits = sizeof (BITMAPFILEHEADER) + pFmt->biSize; if (pFmt->biCompression == BI_BITFIELDS) { bmfHdr.bfSize += 3 * sizeof(DWORD); bmfHdr.bfOffBits += 3 * sizeof(DWORD); } if (pFmt->biBitCount == 8) { bmfHdr.bfSize += 256 * sizeof(RGBQUAD); bmfHdr.bfOffBits += 256 * sizeof(RGBQUAD); } // Write the file header WriteFile(hFile, &bmfHdr, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL); // Write the DIB header and the bits WriteFile(hFile, pFmt, pFmt->biSize, &dwBytesWritten, NULL); // Write RGBMASK if needed if (pFmt->biCompression == BI_BITFIELDS) { WriteFile(hFile, bits565, 3 * sizeof(DWORD), &dwBytesWritten, NULL); } // Write GRAYSCALE palette if needed if (pFmt->biBitCount == 8) { RGBQUAD pal[256]; for (int i=0; i<256; i++) { pal[i].rgbBlue = i; pal[i].rgbGreen = i; pal[i].rgbRed = i; pal[i].rgbReserved = 0; } WriteFile(hFile, pal, 256 * sizeof(RGBQUAD), &dwBytesWritten, NULL); } // Write bits dwBytesWritten = 0; WriteFile(hFile, p, pFmt->biSizeImage, &dwBytesWritten, NULL); CloseHandle(hFile); return dwBytesWritten; } int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int nWidth = 0; int nHeight = 0; PBYTE pJ2C = NULL; int nJ2CSize = 0; BITMAPINFOHEADER bi; char szMsg[501]; // Init BITMAPINFOHEADER ZeroMemory(&bi, sizeof(BITMAPINFOHEADER)); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biPlanes = 1; //-------------------------------------------------------- // DECOMPRESSION //-------------------------------------------------------- //-------------------------------------------------------- // Using IMJ2Dec //-------------------------------------------------------- nJ2CSize = LoadJ2C("Frame.j2c", &pJ2C); if (pJ2C && nJ2CSize) { // Extract width and height from J2C header if (((PWORD)pJ2C)[1] == SIZ) // Be sure we have a SIZ marker here { nWidth = FCC(((PDWORD)pJ2C)[2]); nHeight = FCC(((PDWORD)pJ2C)[3]); // Decode to RGB32 bi.biWidth = nWidth; bi.biHeight = nHeight; bi.biBitCount = 32; bi.biCompression = BI_RGB; bi.biSizeImage = DIBSIZE(bi); // Macro defined in JPEG2000.h // Alloc output buffer PBYTE pOut = (PBYTE)malloc(bi.biSizeImage); if (pOut) { // Decode one frame int nRead = Decode(nWidth, nHeight, pJ2C, nJ2CSize, pOut, bi.biSizeImage, bi.biCompression, bi.biBitCount); SaveDIB("FrameRGB32.bmp", &bi, pOut); wsprintf(szMsg, "Decode Frame.j2c to FrameRGB32.bmp - %dx%d - In: %d (read %d) bytes - Out: %d bytes", nWidth, nHeight, nJ2CSize, nRead, bi.biSizeImage); MessageBox(GetDesktopWindow(), szMsg, "Simple Examples", 0); // Decode Half to RGB32 int skip_level = 1; bi.biWidth = nWidth/(1 << skip_level); bi.biHeight = nHeight/(1 << skip_level); bi.biBitCount = 32; bi.biCompression = BI_RGB; bi.biSizeImage = DIBSIZE(bi); // Macro defined in JPEG2000.h // Decode one frame half resolution nRead = DecodeSkip(nWidth, nHeight, pJ2C, nJ2CSize, skip_level, pOut, bi.biSizeImage, bi.biCompression, bi.biBitCount); SaveDIB("FrameHalfRGB32.bmp", &bi, pOut); wsprintf(szMsg, "Decode Frame.j2c to FrameHalfRGB32.bmp - In: %dx%d %d (read %d) bytes - Out: %dx%d %d bytes", nWidth, nHeight, nJ2CSize, nRead, bi.biWidth, bi.biHeight, bi.biSizeImage); MessageBox(GetDesktopWindow(), szMsg, "Simple Examples", 0); // Free output buffer free(pOut); pOut = NULL; } } } // Free J2C buffer if (pJ2C) { free(pJ2C); pJ2C = NULL; } //-------------------------------------------------------- // Using CMJ2DecMT //-------------------------------------------------------- PBYTE pJ2C_2 = NULL; int nJ2CSize_2 = 0; nJ2CSize = LoadJ2C("Field1.j2c", &pJ2C); nJ2CSize_2 = LoadJ2C("Field2.j2c", &pJ2C_2); if (pJ2C && nJ2CSize && pJ2C_2 && nJ2CSize_2) { // Extract width and height from J2C header if (((PWORD)pJ2C)[1] == SIZ) // Be sure we have a SIZ marker here { nWidth = FCC(((PDWORD)pJ2C)[2]); nHeight = FCC(((PDWORD)pJ2C)[3]); // 2 fields decoded to 1 frame ... nHeight *= 2; // Decode to YUY2 bi.biWidth = nWidth; bi.biHeight = nHeight; bi.biBitCount = 16; bi.biCompression = YUY2; bi.biSizeImage = DIBSIZE(bi); // Macro defined in JPEG2000.h // Alloc output buffer PBYTE pOut = (PBYTE)malloc(bi.biSizeImage); if (pOut) { // Decode two fields to one frame int nRead = Decode2Fields(nWidth, nHeight, pJ2C, nJ2CSize, pJ2C_2, nJ2CSize_2, pOut, bi.biSizeImage, bi.biCompression, bi.biBitCount); SaveDIB("Frame2FieldsYUY2.bmp", &bi, pOut); wsprintf(szMsg, "Decode Field1.j2c + Field2.j2c to Frame2FieldsYUY2.bmp - %dx%d - In: %d (read %d) bytes - Out: %d bytes", nWidth, nHeight, nJ2CSize+nJ2CSize_2, nRead, bi.biSizeImage); MessageBox(GetDesktopWindow(), szMsg, "Simple Examples", 0); free(pOut); pOut = NULL; } // 2 fields decoded to 2 images ... nHeight /= 2; // Decode to UYVY bi.biWidth = nWidth; bi.biHeight = nHeight; bi.biBitCount = 16; bi.biCompression = UYVY; bi.biSizeImage = DIBSIZE(bi); // Macro defined in JPEG2000.h // Alloc output buffer PBYTE pOut1 = (PBYTE)malloc(bi.biSizeImage); PBYTE pOut2 = (PBYTE)malloc(bi.biSizeImage); if (pOut1 && pOut2) { // Decode two fields to two images int nRead = Decode2Frames(nWidth, nHeight, pJ2C, nJ2CSize, pJ2C_2, nJ2CSize_2, pOut1, bi.biSizeImage, pOut2, bi.biSizeImage, bi.biCompression, bi.biBitCount); SaveDIB("Field1UYVY.bmp", &bi, pOut1); SaveDIB("Field2UYVY.bmp", &bi, pOut2); wsprintf(szMsg, "Decode Field1.j2c + Field2.j2c to Field1UYVY.bmp + Field1UYVY.bmp - %dx%d - In: %d (read %d) bytes - Out: %d bytes", nWidth, nHeight, nJ2CSize+nJ2CSize_2, nRead, bi.biSizeImage * 2); MessageBox(GetDesktopWindow(), szMsg, "Simple Examples", 0); } if (pOut1) {free(pOut1);} if (pOut2) {free(pOut2);} pOut1 = NULL; pOut2 = NULL; } } // Free J2C buffers if (pJ2C) {free(pJ2C);} if (pJ2C_2) {free(pJ2C_2);} pJ2C = NULL; pJ2C_2 = NULL; //-------------------------------------------------------- // COMPRESSION //-------------------------------------------------------- //-------------------------------------------------------- // Using CMJ2Enc //-------------------------------------------------------- PBYTE pIn = NULL; ZeroMemory(&bi, sizeof(BITMAPINFOHEADER)); int nIn = LoadDIB("FrameRGB32.bmp", &bi, &pIn); if (pIn && nIn) { // Alloc a buffer large enough to receive codestream. int nOut = nIn; PBYTE pOut = (PBYTE)malloc(nOut); if (pOut) { // Encode one frame int nEncSize = Encode(bi.biWidth, bi.biHeight, pIn, nIn, bi.biCompression, bi.biBitCount, pOut, nOut, 75); // Quality = 0.75 bytes per pixel SaveJ2C("FrameRGB32.j2c", pOut, nEncSize); wsprintf(szMsg, "Encode FrameRGB32.bmp to FrameRGB32.j2c - %dx%d - In: %d bytes - Out: %d bytes", bi.biWidth, bi.biHeight, nIn, nEncSize); MessageBox(GetDesktopWindow(), szMsg, "Simple Examples", 0); // Free output buffer free(pOut); pOut = NULL; } } // Free input buffer if (pIn) {free(pIn);} pIn = NULL; //-------------------------------------------------------- // Using CMJ2EncMT //-------------------------------------------------------- PBYTE pIn1 = NULL; PBYTE pIn2 = NULL; int nIn1 = 0; int nIn2 = 0; BITMAPINFOHEADER bi2; ZeroMemory(&bi2, sizeof(BITMAPINFOHEADER)); // Load 1 frame nIn1 = LoadDIB("Frame2FieldsYUY2.bmp", &bi, &pIn1); if (pIn1 && nIn1) { // Alloc bufferé large enough to receive codestreams. int nOut1 = nIn1; PBYTE pOut1 = (PBYTE)malloc(nOut1); int nOut2 = nIn1; PBYTE pOut2 = (PBYTE)malloc(nOut2); if (pOut1 && pOut2) { // Encode two fields from one frame int nEncSize = Encode2Fields(bi.biWidth, bi.biHeight, pIn1, nIn1, bi.biCompression, bi.biBitCount, pOut1, nOut1, pOut2, nOut2, 75); // Quality = 0.75 bytes per pixel SaveJ2C("Field1YUY2.j2c", pOut1, nOut1); SaveJ2C("Field2YUY2.j2c", pOut2, nOut2); wsprintf(szMsg, "Encode Frame2FieldsYUY2.bmp to Field1YUY2.j2c + Field2YUY2.j2c - In: %dx%d %d bytes - Out: %dx%d %d bytes - Field1: %d bytes - Field2: %d bytes", bi.biWidth, bi.biHeight, nIn1, bi.biWidth, bi.biHeight/2, nEncSize, nOut1, nOut2); MessageBox(GetDesktopWindow(), szMsg, "Simple Examples", 0); // Free input frame free(pIn1); pIn1 = NULL; // Load 2 Images nIn1 = LoadDIB("Field1UYVY.bmp", &bi, &pIn1); nIn2 = LoadDIB("Field2UYVY.bmp", &bi2, &pIn2); if (pIn1 && nIn1 && pIn2 && nIn2) { // Encode two fields from two images nEncSize = Encode2Frames(bi.biWidth, bi.biHeight, pIn1, nIn1, pIn2, nIn2, bi.biCompression, bi.biBitCount, pOut1, nOut1, pOut2, nOut2, 75); // Quality = 0.75 bytes per pixel SaveJ2C("Field1UYVY.j2c", pOut1, nOut1); SaveJ2C("Field2UYVY.j2c", pOut2, nOut2); wsprintf(szMsg, "Encode Field1UYVY.bmp + Field2UYVY.bmp to Field1UYVY.j2c + Field1UYVY.j2c - In: %dx%d %d bytes - Out: %dx%d %d bytes - Field1: %d bytes - Field2: %d bytes", bi.biWidth, bi.biHeight, nIn1, bi.biWidth, bi.biHeight, nEncSize, nOut1, nOut2); MessageBox(GetDesktopWindow(), szMsg, "Simple Examples", 0); } // Free output buffers free(pOut1); pOut1 = NULL; free(pOut2); pOut2 = NULL; } } // Free input buffers if (pIn1) {free(pIn1);} if (pIn2) {free(pIn2);} pIn1 = NULL; pIn2 = NULL; // Done ... MessageBox(GetDesktopWindow(), "Click OK to Exit", "Simple Examples", 0); return 0; }
|
© Morgan Multimedia 1990-2005 |