[wx-dev] Support for SGI RGB file format
Tonda Míšek
miseka at naxo.net
Mon Jul 7 12:33:37 PDT 2008
Hello,
we need to read SGI RGB files so I implemented appropriate wxImageHandler.
I used source code from
http://local.wasp.uwa.edu.au/~pbourke/dataformats/sgirgb/ and
wxPNMHandler as template.
The support is not fully complete, only RGB, RGBA, G and GA with one
byte per color formats are supported, SaveFile is not implemented.
The original autor Paul Bourke agrees with publication under wxWidgets
licence so you can use it in mainstream.
Have a nice day,
Antonín Míšek
/////////////////////////////////////////////////////////////////////////////
// Name: imagrgb.cpp
// Purpose: wxImage RGB handler
// Author: Paul Bourke & Antonin Misek
// RCS-ID:
// Copyright: (c)
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
//#if wxUSE_IMAGE && wxUSE_RGB
#include "imagrgb.h"
#ifndef WX_PRECOMP
#include "wx/intl.h"
#include "wx/log.h"
#endif
#include "wx/txtstrm.h"
//-----------------------------------------------------------------------------
// wxRGBHandler
//-----------------------------------------------------------------------------
//IMPLEMENT_DYNAMIC_CLASS(wxRGBHandler,wxImageHandler)
//#if wxUSE_STREAMS
void wxRGBHandler::ConvertShort(unsigned short *array, long length)
{
unsigned b1, b2;
unsigned char *ptr;
ptr = (unsigned char *)array;
while (length--) {
b1 = *ptr++;
b2 = *ptr++;
*array++ = (b1 << 8) | (b2);
}
}
void wxRGBHandler::ConvertLong(unsigned *array, long length)
{
unsigned b1, b2, b3, b4;
unsigned char *ptr;
ptr = (unsigned char *)array;
while (length--) {
b1 = *ptr++;
b2 = *ptr++;
b3 = *ptr++;
b4 = *ptr++;
*array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
}
}
ImageRec *wxRGBHandler::ImageOpen(wxBufferedInputStream &buf_stream)
{
union {
int testWord;
char testByte[4];
} endianTest;
ImageRec *img;
int swapFlag;
int x;
endianTest.testWord = 1;
if (endianTest.testByte[0] == 1) {
swapFlag = 1;
} else {
swapFlag = 0;
}
// Read the RGB header
img = (ImageRec *)malloc(sizeof(ImageRec));
if (img == NULL) {
wxLogError(_("RGB: Out of memory."));
return NULL;
}
buf_stream.Read(img, 12);
if (swapFlag) {
ConvertShort(&img->imagic, 6);
}
img->tmp = (unsigned char *)malloc(img->xsize*256);
img->tmpR = (unsigned char *)malloc(img->xsize*256);
img->tmpG = (unsigned char *)malloc(img->xsize*256);
img->tmpB = (unsigned char *)malloc(img->xsize*256);
if (img->tmp == NULL || img->tmpR == NULL || img->tmpG == NULL || img->tmpB == NULL) {
wxLogError(_("RGB: Out of memory."));
return NULL;
}
if ((img->type & 0xFF00) == 0x0100) {
x = img->ysize * img->zsize * sizeof(unsigned);
img->rowStart = (unsigned *)malloc(x);
img->rowSize = (int *)malloc(x);
if (img->rowStart == NULL || img->rowSize == NULL) {
wxLogError(_("RGB: Out of memory."));
return NULL;
}
img->rleEnd = 512 + (2 * x);
buf_stream.SeekI(512);
buf_stream.Read(img->rowStart, x);
buf_stream.Read(img->rowSize, x);
if (swapFlag) {
ConvertLong(img->rowStart, x/(int)sizeof(unsigned));
ConvertLong((unsigned *)img->rowSize, x/(int)sizeof(int));
}
} else {
img->rowStart = NULL;
img->rowSize = NULL;
}
return img;
}
void wxRGBHandler::ImageClose(ImageRec *img)
{
free(img->tmp);
free(img->tmpR);
free(img->tmpG);
free(img->tmpB);
free(img->rowSize);
free(img->rowStart);
free(img);
}
void wxRGBHandler::ImageGetRow(wxBufferedInputStream &buf_stream, ImageRec *img, unsigned char *buf, int y, int z)
{
unsigned char *iPtr, *oPtr, pixel;
int count;
if ((img->type & 0xFF00) == 0x0100) {
buf_stream.SeekI((long)img->rowStart[y+z*img->ysize]);
buf_stream.Read(img->tmp, (unsigned int)img->rowSize[y+z*img->ysize]);
iPtr = img->tmp;
oPtr = buf;
for (;;) {
pixel = *iPtr++;
count = (int)(pixel & 0x7F);
if (!count) {
return;
}
if (pixel & 0x80) {
while (count--) {
*oPtr++ = *iPtr++;
}
} else {
pixel = *iPtr++;
while (count--) {
*oPtr++ = pixel;
}
}
}
} else {
buf_stream.SeekI(512+(y*img->xsize)+(z*img->xsize*img->ysize));
buf_stream.Read(buf, img->xsize);
}
}
bool wxRGBHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
{
image->Destroy();
wxBufferedInputStream buf_stream(stream);
unsigned char *rbuf, *gbuf, *bbuf, *abuf;
ImageRec *img;
int y;
img = ImageOpen(buf_stream);
if(!img)
return false;
image->Create( img->xsize, img->ysize );
if (((img->zsize>=4)||(img->zsize==2)) && (!image->HasAlpha()))
image->InitAlpha();
rbuf = (unsigned char *)malloc(img->xsize*sizeof(unsigned char));
gbuf = (unsigned char *)malloc(img->xsize*sizeof(unsigned char));
bbuf = (unsigned char *)malloc(img->xsize*sizeof(unsigned char));
abuf = (unsigned char *)malloc(img->xsize*sizeof(unsigned char));
if(!rbuf || !gbuf || !bbuf)
return false;
for (y=0; y<img->ysize; y++) {
if (img->zsize>=4) {
ImageGetRow(buf_stream, img,rbuf,y,0);
ImageGetRow(buf_stream, img,gbuf,y,1);
ImageGetRow(buf_stream, img,bbuf,y,2);
ImageGetRow(buf_stream, img,abuf,y,3);
for (int x=0; x<img->xsize; x++)
{
image->SetRGB(x, y, rbuf[x], gbuf[x], bbuf[x]);
image->SetAlpha(x, y, abuf[x]);
}
} else if(img->zsize==3) {
ImageGetRow(buf_stream, img,rbuf,y,0);
ImageGetRow(buf_stream, img,gbuf,y,1);
ImageGetRow(buf_stream, img,bbuf,y,2);
for (int x=0; x<img->xsize; x++)
{
image->SetRGB(x, y, rbuf[x], gbuf[x], bbuf[x]);
}
} else if(img->zsize==2) {
ImageGetRow(buf_stream, img,rbuf,y,0);
ImageGetRow(buf_stream, img,abuf,y,1);
for (int x=0; x<img->xsize; x++)
{
image->SetRGB(x, y, rbuf[x], rbuf[x], rbuf[x]);
image->SetAlpha(x, y, abuf[x]);
}
} else {
ImageGetRow(buf_stream, img,rbuf,y,0);
for (int x=0; x<img->xsize; x++)
{
image->SetRGB(x, y, rbuf[x], rbuf[x], rbuf[x]);
}
}
}
ImageClose(img);
free(rbuf);
free(gbuf);
free(bbuf);
free(abuf);
return true;
}
bool wxRGBHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool WXUNUSED(verbose) )
{
return false;
/* wxTextOutputStream text_stream(stream);
//text_stream << "P6" << endl
//<< image->GetWidth() << " " << image->GetHeight() << endl
//<< "255" << endl;
text_stream << wxT("P6\n") << image->GetWidth() << wxT(" ") << image->GetHeight() << wxT("\n255\n");
stream.Write(image->GetData(),3*image->GetWidth()*image->GetHeight());
return stream.IsOk();*/
}
bool wxRGBHandler::DoCanRead( wxInputStream& stream )
{
if ( (stream.GetC() == 1) && (stream.GetC() == 218))
return true;
return false;
}
//#endif // wxUSE_STREAMS
//#endif // wxUSE_IMAGE && wxUSE_RGB
------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
// Name: imagrgb.h
// Purpose: wxImage RGB handler
// Author: Paul Bourke & Antonin Misek
// RCS-ID:
// Copyright: (c)
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_IMAGRGB_H_
#define _WX_IMAGRGB_H_
#include "wx/image.h"
typedef struct _ImageRec {
unsigned short imagic;
unsigned short type;
unsigned short dim;
unsigned short xsize, ysize, zsize;
unsigned int min, max;
unsigned int wasteBytes;
char name[80];
unsigned long colorMap;
FILE *file;
unsigned char *tmp, *tmpR, *tmpG, *tmpB;
unsigned long rleEnd;
unsigned int *rowStart;
int *rowSize;
} ImageRec;
//-----------------------------------------------------------------------------
// wxRGBHandler
//-----------------------------------------------------------------------------
//#if wxUSE_RGB
class WXDLLEXPORT wxRGBHandler : public wxImageHandler
{
public:
inline wxRGBHandler()
{
m_name = wxT("RGB file");
m_extension = wxT("rgb");
m_type = wxBITMAP_TYPE_ANY;//wxBITMAP_TYPE_RGB;
m_mime = wxT("image/rgb");
}
#if wxUSE_STREAMS
virtual bool LoadFile( wxImage *image, wxInputStream& stream, bool verbose=true, int index=-1 );
virtual bool SaveFile( wxImage *image, wxOutputStream& stream, bool verbose=true );
protected:
virtual bool DoCanRead( wxInputStream& stream );
#endif
private:
// DECLARE_DYNAMIC_CLASS(wxRGBHandler)
void ConvertShort(unsigned short *array, long length);
void ConvertLong(unsigned *array, long length);
ImageRec *ImageOpen(wxBufferedInputStream &buf_stream);
void ImageClose(ImageRec *img);
void ImageGetRow(wxBufferedInputStream &buf_stream, ImageRec *img, unsigned char *buf, int y, int z);
};
//#endif
#endif
// _WX_IMAGRGB_H_
More information about the wx-dev
mailing list