Main Page | Modules | Class Hierarchy | Data Structures | File List | Data Fields | Globals | Related Pages | Examples

simple_examples.cpp

Simple Examples Demo which uses:

#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