Click here to Skip to main content
Email Password   helpLost your password?

Preface

Years after the previous version, I can tell that the article has survived its author, and even if my opinion on the limits of this library has not changed, an update was really necessary.

Thank you very much to all the people that gave their contribution to this new release, with hundreds of small and big enhancements, my role was mainly to put all the pieces together.

Introduction & License

CxImage is a C++ class that can load, save, display, and transform images in a very simple and fast way.

The class CxImage is free; as for the TIFF, JPEG, PNG and ZLIB libraries : "If you use this source code in a product, acknowledgement is not required but would be appreciated."

CxImage is open source and licensed under the zlib license . In a nutshell, this means that you can use the code however you wish, as long as you don't claim it as your own.

What's New in Version 6.00

The complete list of bugfixes and enhancements is reported in the documentation, (see \doc\cximage_history.htm, or this link). Here I will highlight some of the new features.

An application written with CxImage version 5.99 should work also with the new version; the interface of few methods is different, normally because of new parameters, but the default behaviour is the same.

The applications linked with the old DLL will not work with the new one; but if necessary you can edit the declarations, or add new overloads, and revert to the old interface for the DLL. An issue to take care is ENUM_CXIMAGE_FORMATS: in the old version the CXIMAGE_FORMAT_... can change the value, depending on the supported formats enabled by the corresponding CXIMAGE_SUPPORT_... switch. In the new version, CXIMAGE_FORMAT_... are assigned to unique values. Static methods like GetNumTypes, GetTypeIdFromName, GetTypeIdFromIndex, GetTypeIndexFromId will help the application to manage the new policy.

File Formats & Linked C Libraries

CxImage works with the latest version of these libraries: Zlib (1.2.3), Jasper ( 1.900.1), LibMNG (1.0.10), LibPNG (1.2.24). LibTIFF 3.8.2 can be linked with CxImage, but the version included in the CxImage distribution (3.5.7, patched) can read images with OJPEG compression, or with non standard bit per samples. The choice is up to you.

The j2k library (now openjpeg), and the associated class CxImageJ2K, have been removed from the project. JPEG2000 images are supported through Jasper and CxImageJAS.

CxImage 6.00 includes a new class (CxImageRAW) and a new library (LibDCR) to read RAW images from digital cameras; common file extension are: RAW, CRW, NEF, CR2, DNG, ORF, ARW, ERF, 3FR, DCR, X3F, MEF, RAF, MRW, PEF, SR2. LibDCR is based on Dave Coffin's dcraw.c; and offers the same features of the original dcraw application (see the "dcr.dsw" project included in the \raw directory). The restricted features under the GPL Version 2 are disabled; please read the license terms in "libdcr.h" before enabling the restricted code.

CxImageRAW implements the basic functions to decode the image, the only available option controlled by SetCodecOption, is about the interpolation quality (DECODE_QUALITY_LIN=0, DECODE_QUALITY_VNG=1, DECODE_QUALITY_PPG=2, DECODE_QUALITY_AHD=3).

CxImagePNG has been improved to read and write all of the PNG_COLOR_TYPE_... combinations. PNGs with a "pixel depth" more that 8 bits per channel will be converted down to 8 bits, this is the major limit in CxImage.

CxImageGIF: better support for reading animated GIF, now can decode all frames in a single pass, if enabled with SetRetreiveAllFrames. The CxImage demo implements this option, and shows how to play an animated GIF (when the program asks "File with N images. Read all?", select "Cancel").

CxImageBMP: reads and writes 32 bit images (with alpha layer).
CxImageICO: reads and writes Vista (PNG) icons; and added support for writing multipage icons.
CxImageMNG: reads MNGs with alpha layer.
CxImageSKA: new class for SKA image format, used in some video rental application.

CxImageJPG: new options for the JPEG format subsampling (ENCODE_SUBSAMPLE_422, ENCODE_SUBSAMPLE_444), default is 4:1:1 (high), can be set to 4:2:2 (medium) or 4:4:4 (none).

The next table shows the different amount of artifacts in the compressed image, using to different subsampling. 4:4:4 subsampling is useful in images with sharp edges, to reduce the typical blurring effect of the JPG compression.


original image

JPG image and artefacts,
quality 75, subsampling 4:1:1

JPG image and artefacts,
quality 75, subsampling 4:4:4

Portability

The class and the projects have been tested with different compilers, from Microsoft VC++6 to VC++2008, with Borland C++ Builder 3 and 6, and partially with wxDev-C++ and MinGW.

UNICODE and non-UNICODE configurations are provided for all the libraries (thanks to Eric Jesover).

A light version (cximage600_lite) without the C libraries and with a small demo is provided for the first time users, or as a basic template, without the clutter of the full demo project.

The console (\demo2) and the CxImageCrtDll projects can be built with VC++Express2005 and the Microsoft Platform SDK. If you get linker errors like "unresolved external...", check if all the C libraries have been compiled (set the correct project dependencies), or add the gdi32.lib and user32.lib modules to the Linker\Input\Additional Dependencies property.

CxImage works also with Pocket PC 2003; a working version and demo (cximage600_ce) are provided for the VC++2005 compiler (thanks to Vincent Richomme). For the old embedded VC compilers, the main limit was the support for exception handling. To overcome this problem, the try, throw and catch statements have been replaced with 3 macros (defined in ximadef.h), and with the definition of CXIMAGE_SUPPORT_EXCEPTION_HANDLING; in this way it is possible to build the library without exception handling support. Maybe the solution is not so elegant, but the impact on the source code is minimal when exception handling is disabled, while there are no changes in case of exception handling enabled.

The compatibility between little-endian and big-endian platforms, for the built in formats (bmp, ico, tga, pcx, gif, ska) is handled by ntohs and ntohl.

Demo

Almost all the new features can be tested in the main CxImage demo application. The demo is just a test bench, even if it offers some nice features, it is not intended to be a serious application.

CxImage Structure

In the vertical hierarchy of the library, CxImage stays on the top of the other modules, it's not a clean OOP approach, but the result was good since the first release and now it's too late to change again. Anyway you can always use the derived classes to perform the format specific operations, like for CxImageTIF to save multipage TIFFs.

The glue to connect all the modules and the C libraries is CxFile, a virtual class that provides the standard methods to access the data from a file on the disk or in memory.

A Cximage object is basically a bitmap, with the addition of some member variables to store useful information:

 class CxImage
  {
  ...
  protected:
  void* pDib;            //contains the header, the palette, the pixels
  BITMAPINFOHEADER head; //standard header
  CXIMAGEINFO info;      //extended information
  BYTE* pSelection;      //selected region
  BYTE* pAlpha;          //alpha channel
  CxImage** ppLayers;     //generic layers
  CxImage** ppFrames;     //frames for animation
  }

CxImage::head is the bitmap header and CxImage::pDib is a normal bitmap (as you can see in the implementation of CxImageBMP::Encode).

CxImage::info is a handy container of many information shared between different formats, and for all the member functions.

typedef struct tagCxImageInfo {
    DWORD   dwEffWidth;       //DWORD aligned scan line width
    BYTE*   pImage;           //THE IMAGE BITS
    void*   pGhost;           //if this is a ghost, pGhost point to the body
    DWORD   dwType;           //original image format
    char    szLastError[256]; //debugging
    long    nProgress;        //monitor
    long    nEscape;          //escape
    long    nBkgndIndex;      //used for GIF, PNG, MNG
    RGBQUAD nBkgndColor;      //used for RGB transparency
    BYTE    nQuality;         //used for JPEG
    long    nFrame;           //used for TIF, GIF, MNG : actual frame
    long    nNumFrames;       //used for TIF, GIF, MNG : total number of 
                              //frames
    DWORD   dwFrameDelay;     //used for GIF, MNG
    long    xDPI;             //horizontal resolution
    long    yDPI;             //vertical resolution
    RECT    rSelectionBox;    //bounding rectangle
    BYTE    nAlphaMax;        //max opacity (fade)
    bool    bAlphaPaletteEnabled;  //true if alpha values in the palette are 
                              // enabled.
    bool    bEnabled;         //enables the painting functions
    long    xOffset;
    long    yOffset;
    DWORD   dwEncodeOption;   //for GIF, TIF : 0=def.1=unc,2=fax3,3=fax4,
                              // 4=pack,5=jpg
    RGBQUAD last_c;           //for GetNearestIndex optimization
    BYTE    last_c_index;
    bool    last_c_isvalid;
    long    nNumLayers;
    DWORD   dwFlags;
} CXIMAGEINFO;

A CxImage object is also a set of layers. The buffers in each layer are allocated only when necessary.

CxImage::pDib is the background image. CxImage::pAlpha is the transparency layer. CxImage::pSelection is the selection layer, used to create regions of interest for image processing. Over these 3 specific planes, you can add other generic layers, stored in CxImage::ppLayers. The generic layers are full CxImage objects, so you can build complex structures of nested layers. CxImage::ppFrames is reserved for animated images (GIF)

CxImage Class Members & Operations

CxImage is documented using Doxygen , however for historical reasons, many uncommon features are still undocumented. The class members reference, together with release history, and license, can be found here

Supported Formats and Options

The whole library is quite big, in the main header file ximcfg.h you'll find the switches to enable or disable a specific graphic format or feature. Each JPG, PNG and TIFF library adds about 100KB to the final application, while the CxImage impact is about 50KB. So you should support and link only the formats that your application really needs.

formats #define required libraries size [Kbyte]
BMP
GIF
ICO
TGA
PCX
WBMP
WMF
SKA
CXIMAGE_SUPPORT_BMP
CXIMAGE_SUPPORT_GIF
CXIMAGE_SUPPORT_ICO
CXIMAGE_SUPPORT_TGA
CXIMAGE_SUPPORT_PCX
CXIMAGE_SUPPORT_WBMP
CXIMAGE_SUPPORT_WMF
CXIMAGE_SUPPORT_SKA

built in

24
JPEG CXIMAGE_SUPPORT_JPG
jpeg

88
PNG CXIMAGE_SUPPORT_PNG
png, zlib

104
MNG CXIMAGE_SUPPORT_MNG
mng, zlib, jpeg

148
TIFF CXIMAGE_SUPPORT_TIF
tiff, zlib, jpeg

124
JBIG CXIMAGE_SUPPORT_JBG
jbig

28
PNM,PPM,PGM
RAS
CXIMAGE_SUPPORT_PNM
CXIMAGE_SUPPORT_RAS

jasper

176
JPEG-2000 CXIMAGE_SUPPORT_JP2
CXIMAGE_SUPPORT_JPC
CXIMAGE_SUPPORT_PGX

jasper

176
RAW CXIMAGE_SUPPORT_RAW libdcr 132

Option #define Size [Kbyte]
CxImage core all switches off 20
geometric transformations CXIMAGE_SUPPORT_TRANSFORMATION 16
image processing CXIMAGE_SUPPORT_DSP 24
drawing and windows specific functions CXIMAGE_SUPPORT_WINDOWS 12
transparency CXIMAGE_SUPPORT_ALPHA 4
selections CXIMAGE_SUPPORT_SELECTION 4
multiple layers CXIMAGE_SUPPORT_LAYERS < 4
graphic formats conversion CXIMAGE_SUPPORT_DECODE
CXIMAGE_SUPPORT_ENCODE
< 4
interpolation functions CXIMAGE_SUPPORT_INTERPOLATION < 4
exception handling CXIMAGE_SUPPORT_EXCEPTION_HANDLING < 4

Using CxImage in your Projects

The CxImgLib.dsw workspace shows the libraries required to build an application (demo.exe) including almost all the features and the formats available in CxImage. You must compile all the libraries before you can link the final application.
In the same workspace you'll find the projects to build different libraries and applications:

  • CxImage : cximage.lib - static library
  • CxImageCrtDll : cximagecrt.dll - DLL not using mfc
  • CxImageMfcDll : cximage.dll - DLL using mfc
  • Demo : demo.exe - program linked with cximage.lib and the C libraries
  • DemoDll : demodll.exe - program linked with cximagecrt.dll
  • libdcr,jasper,jbig,jpeg,png,tiff,zlib : static C libraries

Building the projects will need some minutes to complete. When everything is done, select the demo project and launch the application.

CxImgLib.dsw

To use CxImage in your project, you must edit these settings:

Project Settings
 |- C/C++
 |   |- Code Generation
 |   |   |- Use run-time library : Multithreaded DLL (must be the same for 
 |   |   |  all the linked libraries)
 |   |   |- Struct member alignment : must be the same for all the linked 
 |   |   |  libraries
 |   |- Precompiled headers : not using precompiled headers
 |   |- Preprocessor
 |       |- Additional Include Directories:  ..\cximage
 |- Link
    |- General
        |- Object/library modules: ../png/Debug/png.lib  
                                   ../raw/Debug/libdcr.lib
                                   ../jpeg/Debug/jpeg.lib 
                                   ../zlib/Debug/zlib.lib 
                                   ../tiff/Debug/tiff.lib
                                   ../jasper/Debug/jasper.lib
                                   ../cximage/Debug/cximage.lib  ...

In your source code you must add #include "ximage.h"

Note: don't mix debug and release modules; each configuration must use its respective library modules.

Adding your Custom Functions in CxImage

Writing a new function for image processing is not so hard with CxImage. Here I'm going to describe CxImage::Jitter — it's very simple but it shows many aspects to take care of when you work inside CxImage. The first thing, of course, is the declaration : bool Jitter(long radius=2); in the CXIMAGE_SUPPORT_DSP section of ximage.h, you can declare the function everywhere in the public scope of the class. And now the definition:

bool CxImage::Jitter(long radius)
{
    // check if the image is valid, this should be always the first line in 
    // the function 
    if (!pDib) return false;
    
    // local variables
    long nx,ny;
    
    // temporary image to store the partial results of the algorithm
    CxImage tmp(*this,pSelection!=0,true,true);
    
    // limit the effects of the functions only in the smallest rectangle that
    // holds the selected region (defined with the Selection...() functions ),
    // this will speed up the loops.
    long xmin,xmax,ymin,ymax;
    if (pSelection){
        xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
        ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
    } else {
        xmin = ymin = 0;
        xmax = head.biWidth; ymax=head.biHeight;
    }
    
    // main loop : scan the image in vertical direction
    for(long y=ymin; y <ymax; y++){
    
        // monitor the progress of the loops
        info.nProgress = (long)(100*y/head.biHeight);
    
        // let the application a way to exit quickly
        if (info.nEscape) break;
    
        // main loop : scan the image in horizontal direction
        for(long x=xmin; x<xmax; x++){
    
        // if the feature is enabled, process only the pixels inside the 
        // selected region
#if CXIMAGE_SUPPORT_SELECTION
            if (SelectionIsInside(x,y))
#endif //CXIMAGE_SUPPORT_SELECTION
            {
                // main algorithm
                nx=x+(long)((rand()/(float)RAND_MAX - 0.5)*(radius*2));
                ny=y+(long)((rand()/(float)RAND_MAX - 0.5)*(radius*2));
                if (!IsInside(nx,ny)) {
                    nx=x;
                    ny=y;
                }

                // save the result in the temporary image.
                // if you can, use PixelColor only for 24 bpp images,
                // and PixelIndex for 8, 4 and 1 bpp images : it's faster
                if (head.biClrUsed==0){
                    tmp.SetPixelColor(x,y,GetPixelColor(nx,ny));
                } else {
                    tmp.SetPixelIndex(x,y,GetPixelIndex(nx,ny));
                }

                // if the feature is enabled, process also the pixels 
                // in the alpha layer
#if CXIMAGE_SUPPORT_ALPHA
                tmp.AlphaSet(x,y,AlphaGet(nx,ny));
#endif //CXIMAGE_SUPPORT_ALPHA

            }
        }
    }

    // save the result and exit
    Transfer(tmp);
    return true;
}

Examples: How to ...

... Convert from One Format to Another

CxImage  image;
// bmp -> jpg


image.Load("image.bmp", CXIMAGE_FORMAT_BMP);
if (image.IsValid()){
    if(!image.IsGrayScale()) image.IncreaseBpp(24);
    image.SetJpegQuality(80);
    image.Save("image.jpg",CXIMAGE_FORMAT_JPG);
}
// png -> tif


image.Load("image.png", CXIMAGE_FORMAT_PNG);
if (image.IsValid()){
    image.Save("image.tif",CXIMAGE_FORMAT_TIF);
}

... Load an Image Resource

//Load the resource IDR_PNG1 from the PNG resource type


CxImage* newImage = new CxImage();
newImage->LoadResource(FindResource(NULL,MAKEINTRESOURCE(IDR_PNG1),
                       "PNG"),CXIMAGE_FORMAT_PNG);
or
//Load the resource IDR_JPG1 from DLL




CxImage* newImage = new CxImage();
HINSTANCE hdll=LoadLibrary("imagelib.dll");

if (hdll){
    HRSRC hres=FindResource(hdll,MAKEINTRESOURCE(IDR_JPG1),"JPG");
    newImage->LoadResource(hres,CXIMAGE_FORMAT_JPG,hdll);
    FreeLibrary(hdll);
}
or
//Load a bitmap resource;

HBITMAP bitmap = ::LoadBitmap(AfxGetInstanceHandle(),
                              MAKEINTRESOURCE(IDB_BITMAP1)));
CxImage *newImage = new CxImage();
newImage->CreateFromHBITMAP(bitmap);

... Decode an Image from Memory

CxImage image((BYTE*)buffer,size,image_type);
or
CxMemFile memfile((BYTE*)buffer,size);
CxImage image(&memfile,image_type);
or
CxMemFile memfile((BYTE*)buffer,size);
CxImage* image = new CxImage();
image->Decode(&memfile,type);

... Encode an Image in Memory

long size=0;
BYTE* buffer=0;
image.Encode(buffer,size,image_type);
...
image.FreeMemory(buffer);
or
CxMemFile memfile;
memfile.Open();
image.Encode(&memfile,image_type);
BYTE* buffer = memfile.GetBuffer();
long size = memfile.Size();
...
image.FreeMemory(buffer);

... Create a Multipage TIFF

CxImage *pimage[3];
pimage[0]=&image1;
pimage[1]=&image2;
pimage[2]=&image3;

FILE* hFile;
hFile = fopen("multipage.tif","w+b");

CxImageTIF multiimage;
multiimage.Encode(hFile,pimage,3);

fclose(hFile);
or
FILE* hFile;
hFile = fopen("c:\\multi.tif","w+b");

CxImageTIF image;
image.Load("c:\\1.tif",CXIMAGE_FORMAT_TIF);
image.Encode(hFile,true);
image.Load("c:\\2.bmp",CXIMAGE_FORMAT_BMP);
image.Encode(hFile,true);
image.Load("c:\\3.png",CXIMAGE_FORMAT_PNG);
image.Encode(hFile);

fclose(hFile);

... Copy/Paste an Image

//copy

HANDLE hDIB = image->CopyToHandle();
if (::OpenClipboard(AfxGetApp()->m_pMainWnd->GetSafeHwnd())) {
    if(::EmptyClipboard()) {
        if (::SetClipboardData(CF_DIB,hDIB) == NULL ) {
            AfxMessageBox( "Unable to set Clipboard data" );
}    }    }
CloseClipboard();


//paste

HANDLE hBitmap=NULL;
CxImage *newima = new CxImage();
if (OpenClipboard()) hBitmap=GetClipboardData(CF_DIB);
if (hBitmap) newima->CreateFromHANDLE(hBitmap);
CloseClipboard();

... Display a File in a Picture Box

HBITMAP m_bitmap = NULL;
CxImage image("myfile.png", CXIMAGE_FORMAT_PNG);
...
CDC* hdc = m_picture.GetDC();
HBITMAP m_bitmap = image.MakeBitmap(hdc->m_hDC);

HBITMAP hOldBmp = m_picture.SetBitmap(m_bitmap);
if (hOldBmp) DeleteObject(hOldBmp);
if (hdc->m_hDC) m_picture.ReleaseDC(hdc);
...
if (m_bitmap) DeleteObject(m_bitmap);

History and Credits

Starting form my CxDib class, that implements memory DIBs only, I tried to add some members to read images from files. Looking for a solution, I found a nice MFC class named CImage on the net, release 1.4 (1998). CImage supports BMP, GIF, PNG and JPG, but suffers many little bugs and uses a complex class structure, so I decided to strip it to the base and merge CxDib with the CImage philosophy, to obtain the new CxImage class. Also I updated the libraries for JPG, PNG and ZLIB.

With CxImage it is very easy to add new image types, so I added the TIFF library (rev. 6) and a minimal support for ICONs, MNG, TGA and PCX. Finally I added some specific functions to obtain an image from global HANDLEs (windows clipboard) and objects (windows resources). This is the story until the early release, the following is written in the documentation.

More specific credits and disclaimers are in every header file of each library.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
QuestionSemi-transparent text
GenGP
0:44 19 Nov '09  
Hi. Help please. How to show semi-transparent text using this library?
AnswerRe: Semi-transparent text
Davide Pizzolato
13:10 27 Nov '09  
http://www.codeproject.com/Messages/3286760/Re-How-to-add-watermark-text.aspx[^]
GeneralCan't convert to jpeg [modified]
stefanoooooooo
1:29 9 Nov '09  
[edit: solved previous issue]

Hi there,

I just started using CxImage, and I'm doing some experiments on image conversion. I managed to convert one existing png file in a jpg one, now I'm ondering if it's possible to create a jpeg file given only an unsigned char buffer representing the rgb data (i.e. for a 100X100 image, a 30000 unsigned char array, with data stored as r1g1b1r2g2b2 and so on).

Did anybody try something like that?

thanks,
Stefano

modified on Monday, November 9, 2009 6:56 AM

GeneralRe: Can't convert to jpeg
Davide Pizzolato
9:33 9 Nov '09  
use CxImage::CreateFromArray
GeneralRe: Can't convert to jpeg
stefanoooooooo
3:34 10 Nov '09  
Seems like it's not working... if I call
image.CreateFromArray( pucImgData, iImgWidth, iImgHeight, 24, iImgLineSize, false );
then IsValid return false. I also tried to call Create first:
image.Create( iImgWidth, iImgHeight, 24 );
image.CreateFromArray( pucImgData, iImgWidth, iImgHeight, 24, iImgLineSize, false );
but in this case the jpeg created is just a completely grey image.
I managed to solve this way:
unsigned char* pucImg = static_cast<unsigned char*> ( image.Create( iWidth, iHeight, 24 ) );
unsigned char* pucFrame = static_cast<unsigned char*> ( getFrameData() );
int iImgSize = iWidth * iHeight * 3;
for (int i=0; i<iImgSize; i+=3 )
{
pucImg[ 40 + i ] = pucFrame[ iImgSize - i ]; //40 = header size
pucImg[ 41 + i ] = pucFrame[ iImgSize - i - 2 ];
pucImg[ 42 + i ] = pucFrame[ iImgSize - i - 1 ];
}
but it looks really ugly.

Anyway, thanks a lot for the suggestion.
Stefano
Generalgenerate a TIFF
hugtiger
18:08 2 Nov '09  
hi I use VC++ generated a .dat file which contains an array of 16384 numbers
anybody knows how can I generate a 128*128 TIFF image from the .dat file ?
GeneralRe: generate a TIFF
Davide Pizzolato
8:12 3 Nov '09  
use CxImage::CreateFromArray
GeneralCreate 16 bit bmp
raju_Code
19:55 22 Oct '09  
Hello Sir,


How to Create 16 bit bmp ..?? i tried your application its only supported 4,8 and 24 ...but missing 16 bit ...how to increase 16 bit BPP

please help me sir ...please add this functionality ..

Thanks
GeneralRe: Create 16 bit bmp
Davide Pizzolato
10:23 1 Nov '09  
there are many requests about this feature, but in this library it is simply missing by design. In the current release, adding this functionality needs a lot of job.
Generaltiff image warning
luoxing
23:24 15 Oct '09  
unknown field with tag 292 (0x124) ignored

How the error occured?
GeneralRe: tiff image warning
Davide Pizzolato
8:02 16 Oct '09  
only in debug builds; the image contains a tag not handled by the library, and it is ignored.
Generalshape extraction from images
raju_Code
2:53 9 Oct '09  
...i am great fan of this article ...

Thanks for submitting ....

currently i have developing one application , I dont know whether your program Extract shapes from images ...?

if ("YES" == TRUE)
MessageBox("please tell me which function can i use ?")
else MessageBox("How to solve this problem")

return "Please Guide me !! and Help Me"

Thanks Smile
GeneralRe: shape extraction from images
Davide Pizzolato
9:45 9 Oct '09  
http://www.scribd.com/search?internalSearch=true&query=Image+Processing+Handbook[^]
GeneralNeed your help!!!!!!!! [modified]
raju_Code
3:32 1 Oct '09  
Hi

I am new in vc++ and also your CxImage

i want to how to make multi page tiff file ...

  FILE* hFile;
hFile = fopen("1.tif","w+b");
CxImageTIF image;
image.Load(L"2.TIF",CXIMAGE_FORMAT_TIF);
image.Encode(hFile,true);
fclose(hFile);

when i ran that code showing
error LNK2001: unresolved external symbol "public: bool __thiscall CxImage::Load(wchar_t const *,unsigned long)" (?Load@CxImage@@QAE_NPB_WK@Z) MultipageImagesDlg.obj

fatal error LNK1120: 1 unresolved externals D:\Visual Studio Projects\visual Cpp\MFC\MultipageImages\Debug\MultipageImages.exe


what is reason ??
Thanks

modified on Thursday, October 1, 2009 10:12 AM

GeneralRe: Need your help!!!!!!!!
Davide Pizzolato
8:41 1 Oct '09  
probably you are mixing unicode application and non-unicode library, or viceversa.
GeneralRe: Need your help!!!!!!!!
raju_Code
20:24 4 Oct '09  
Hi Thanks for your respons David

i added library..

wininet.lib
../Debug/png.lib
../Debug/libdcr.lib
../Debug/Jpeg.lib
../Debug/zlib.lib
../Debug/Tiff.lib
../Debug/jasper.lib
../Debug/cximage.lib


this way ..only i try many ways till now i can get the same error

error LNK2019: unresolved external symbol "public: bool __thiscall CxImage::Load(wchar_t const *,unsigned long)" (?Load@CxImage@@QAE_NPB_WK@Z) referenced in function "public: void __thiscall CMultipageImagesDlg::OnBnClickedButtonMultipageimages(void)" (?OnBnClickedButtonMultipageimages@CMultipageImagesDlg@@QAEXXZ) MultipageImagesDlg.obj

Please Reply me...

Thanks!!!
AnswerRe: Need your help!!!!!!!!
raju_Code
21:26 4 Oct '09  
Thanks for your support ..now its ok
GeneralCompiling without CxImage libraries while using CxImage as dependent project question VC6.0
Vaclav_Sal
8:58 20 Sep '09  
I am using VC 6.0. After including all necessary libraries (window32 debug) into my project I ended up with problem while debugging – HEAP address mismatch. I deleted all CxImage libraries (from LINK) and added CxImage as a dependent project. My project complied and I can debug my application.
My question is – did I miss something and is this “legal”?
Why does it “work” / compile   or am I going to have problems with release code?
GeneralRe: Compiling without CxImage libraries while using CxImage as dependent project question VC6.0
Davide Pizzolato
9:42 21 Sep '09  
Maybe the libraries and your project use different compiler options.
Can you find the same problem also with the CxImage demo projects?
GeneralDirect JPEG to RGBA conversion?
Autostoppeuse_Galactique
0:26 18 Sep '09  
Hi,

after I was able, thanks to Davide, to build CxImage for Mac Os (and iPhone OS too), I nearly managed to do all the image processing I needed.
The last problem I encounter is CPU ressources.
The operation NewImage(FromBuffer) + Decode(ToBuffer) costs a little more than I expected.

That's why I am now wondering if there is a more economic way to do a direct Decode(FromBuffer,ToBuffer) assuming the "FromBuffer" was an array created by a previous CxImage processing.

My current "expensive" code does convert a image of an unknown format (usually JPEG) to a raw RGBA buffer for OpenGL purpose. Actually, the "unknown" format is not compulsory and I will get rid of it if needed to save CPU time. Here is the source :

bool ExtractJPEGFromArray( 
Byte * p_inData,
long & p_inDataSize,
Byte*& p_outData,
unsigned short & p_outWidth,
unsigned short & p_outHeight,
unsigned short & p_outBitsPerPixel)

{
if (p_outData !=NULL || p_inData == NULL)
return FALSE;

CxImage * newImage = new CxImage();

if (!newImage->Decode(p_inData,p_inDataSize,CXIMAGE_FORMAT_UNKNOWN))
{
Manage("SomeError");
}


if (!newImage->IsValid())
{
Manage("SomeMoreError");
}

long l_RawSize;
BOOL l_ReturnCode = newImage->Encode2RGBA(p_outData,l_RawSize);

p_outWidth = newImage->GetWidth();
p_outHeight = newImage->GetHeight();
p_outBitsPerPixel = 32; // RGBA

delete newImage;

return l_ReturnCode;
}

If you know of a way to do this directly with CxImage, I will be very interested by it.

Thanks for reading.
GeneralRe: Direct JPEG to RGBA conversion?
Davide Pizzolato
10:25 18 Sep '09  
here is a simple idea:

add a member variable to the CXIMAGEINFO structure
typedef struct tagCxImageInfo {

...

CxFile* pOutFile; //<--- could be a file or a memory buffer
} CXIMAGEINFO;
and add a member function to access to the variable: CxFile* CxImage::GetOutFile(); / CxImage::SetOutFile(CxFile* pFile);
edit the decoder where the data are moved from the file to the internal CxImage buffer, to redirect and convert the data to pOutFile
	/* Step 6: while (scan lines remain to be read) */
	/*           jpeg_read_scanlines(...); */
	/* Here we use the library's state variable cinfo.output_scanline as the
* loop counter, so that we don't have to keep track ourselves.
*/
iter.Upset();
while (cinfo.output_scanline < cinfo.output_height) {

if (info.nEscape) longjmp(jerr.setjmp_buffer, 1); // - cancel decoding

(void) jpeg_read_scanlines(&cinfo, buffer, 1);

if (NULL == info.pOutFile) { //--- EDIT HERE ----
// info.nProgress = (long)(100*cinfo.output_scanline/cinfo.output_height);
// Step 6a: CMYK->RGB */
if ((cinfo.num_components==4)&&(cinfo.quantize_colors==FALSE)){
BYTE k,*dst,*src;
dst=iter.GetRow();
src=buffer[0];
for(long x3=0,x4=0; x3<(long)info.dwEffWidth && x4 k=src[x4+3];
dst[x3] =(BYTE)((k * src[x4+2])/255);
dst[x3+1]=(BYTE)((k * src[x4+1])/255);
dst[x3+2]=(BYTE)((k * src[x4+0])/255);
}
} else {
/* Assume put_scanline_someplace wants a pointer and sample count. */ iter.SetRow(buffer[0], row_stride);
}
iter.PrevRow();
} else { //--- EDIT HERE ----
//here manage conversion and transfer from "buffer" to "pOutFile"
}
}

The problem is that each ::Decode uses different methods to read the pixels and fill the CxImage internal buffer
GeneralRe: Direct JPEG to RGBA conversion?
Roger_Rabbit
1:04 22 Sep '09  
Thanks for you answer.

So, let's assume that I am interested only in the JPEG decompression for the moment. I think I may be able to apply this to other formats as soon as I manage to do it for JPEG.

Then, before I start coding, I want to be sure I understood well.

I am a little confused with the jpeg_read_scanlines fonction. I'll try to tell what I have understood :
jpeg_read_scanlines(&cinfo, buffer, 1) 
: reads 1 "decoded" line from the input data into the buffer, that we can then store as a direct RGB line in our member image (doing a quick BGR<->RGB swap). Am I right?

Thus, this would mean I would have to :

- stack up each "scanned line" in pOutFile (pOutFile->Write(scanned_line,size,1)

and then later in some GetRGBABuffer() :
- allocate my pOutBuffer according to the info previously found in cinfo (size = image_width * image_height * num_components)
- Retrieve the raw data from my pOutFile (pOutFile->Read(myOutBuffer,size,1);



Assuming I was right, and since the use of a CxFile implies a memcpy() operation (in ::Read), this looks like one too many operations. Then I'd rather find a way to pass a buffer adress to the decode function to do it the direct way (which sounds possible according to what I think I understood).
Maybe something like
bool 	CxImage::DecodeToMemory (const BYTE *inbuffer, DWORD size, DWORD imagetype, BYTE *outbuffer)

GeneralRe: Direct JPEG to RGBA conversion?
Davide Pizzolato
10:47 22 Sep '09  
my idea was a bit different, because using CxMemFile the final buffer "pOutBuffer" and the object "pOutFile" can share the same memory: pOutBuffer = pOutFile->GetBuffer();
so first you convert the scanned line to RGBA, and then write the data to the file; in this way ths CxMemFile object takes care of the memory allocation.

using jpeg_read_scanlines, control the value in cinfo.num_components, 3 is RGB, 1 is grayscale, 4 is CMYK
QuestionBuilder 6 TImage To CxImage [modified]
Member 6542899
19:15 15 Sep '09  
Hi,

I'm using cximage library for loading an image in a TImage control, suppose "target". After to modify "target" image I have to save these changes (in "target") into another image file. So I tried to do this many times but I couldn't. I use next code for load image into a TImage control:

    // Load image
ximage = new CxImage();
ximage->Load(filename.c_str(),type);
target->Picture->Bitmap->Width = ximage->GetWidth();
target->Picture->Bitmap->Height = ximage->GetHeight();
ximage->Draw(target->Picture->Bitmap->Canvas->Handle);
delete ximage;
return true;

After loading, some changes, lines, paint (use TImage control functions) etc... I try to save "target" as a new file (example "new_image.jpg"). I use:

    CxImage* ximage = new CxImage;
if( ximage->CreateFromHBITMAP( target->Picture->Bitmap->Handle ) )
{
if( !ximage->Save(filename.c_str(), type) )
{
MessageBox(NULL,ximage->GetLastError(),"Error",MB_OK);
delete ximage;
return false;
}
}
delete ximage;
return false;

When I was trying to solve it I made experiments using different image format and it doesn't work if I use jpg images. For example, it works if I use gif or bmp files. Does anybody see a problem in that?

Thanks for your time...

modified on Wednesday, September 16, 2009 1:37 AM

AnswerRe: Builder 6 TImage To CxImage
Davide Pizzolato
11:04 16 Sep '09  
try with ximage->IncreaseBpp(24); before ximage->Save(...)


Last Updated 15 Feb 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010