/////////////////////////////////////////////////////////////////////////////
-// Name: imagpnm.cpp
+// Name: src/common/imagpnm.cpp
// Purpose: wxImage PNM handler
// Author: Sylvain Bougnoux
// RCS-ID: $Id$
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-/*
- We don't put pragma implement in this file because it is already present in
- src/common/image.cpp
-*/
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
-#pragma hdrstop
+ #pragma hdrstop
#endif
-#include "wx/image.h"
-#include "wx/log.h"
-#include "wx/txtstrm.h"
+#if wxUSE_IMAGE && wxUSE_PNM
+
+#include "wx/imagpnm.h"
-#ifdef __WXMSW__
-#include <windows.h>
+#ifndef WX_PRECOMP
+ #include "wx/intl.h"
+ #include "wx/log.h"
#endif
+#include "wx/txtstrm.h"
+
//-----------------------------------------------------------------------------
// wxBMPHandler
//-----------------------------------------------------------------------------
-#if !USE_SHARED_LIBRARIES
IMPLEMENT_DYNAMIC_CLASS(wxPNMHandler,wxImageHandler)
-#endif
#if wxUSE_STREAMS
- //#include <stream.h> // for cout
-
void Skip_Comment(wxInputStream &stream)
{
- wxString line;
- wxTextInputStream text_stream(stream);
+ wxTextInputStream text_stream(stream);
- if (stream.Peek()==_T('#'))
+ if (stream.Peek()==wxT('#'))
{
- text_stream >> line;
- Skip_Comment(stream);
+ text_stream.ReadLine();
+ Skip_Comment(stream);
}
}
-bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool WXUNUSED(verbose) )
+bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
{
wxUint32 width, height;
wxUint16 maxval;
- wxString line;
char c(0);
-
+
image->Destroy();
/*
* Read the PNM header
*/
- wxTextInputStream text_stream(stream);
+ wxBufferedInputStream buf_stream(stream);
+ wxTextInputStream text_stream(buf_stream);
- Skip_Comment(stream);
- if (stream.GetC()==_T('P')) c=stream.GetC();
+ Skip_Comment(buf_stream);
+ if (buf_stream.GetC()==wxT('P')) c=buf_stream.GetC();
switch (c)
- {
- case _T('2'):
- wxLogError(_T("Loading Grey Ascii PNM image is not yet implemented."));
- return FALSE;
- case _T('5'):
- wxLogError(_T("Loading Grey Raw PNM image is not yet implemented."));
- return FALSE;
- case _T('3'): case _T('6'): break;
- default :
- wxLogError(_T("Loading PNM image : file not recognized."));
- return FALSE;
- }
-
- text_stream >> line; // for the \n
- Skip_Comment(stream);
+ {
+ case wxT('2'): // ASCII Grey
+ case wxT('3'): // ASCII RGB
+ case wxT('5'): // RAW Grey
+ case wxT('6'): break;
+ default:
+ if (verbose) wxLogError(_("PNM: File format is not recognized."));
+ return false;
+ }
+
+ text_stream.ReadLine(); // for the \n
+ Skip_Comment(buf_stream);
text_stream >> width >> height ;
- Skip_Comment(stream);
+ Skip_Comment(buf_stream);
text_stream >> maxval;
- //cout << width << " " << height << " " << maxval << endl;
+ //cout << line << " " << width << " " << height << " " << maxval << endl;
image->Create( width, height );
unsigned char *ptr = image->GetData();
if (!ptr)
{
- wxLogError( _T("Cannot allocate RAM for RGB data in PNM file.") );
- return FALSE;
+ if (verbose)
+ wxLogError( _("PNM: Couldn't allocate memory.") );
+ return false;
}
+
+ if (c=='2') // Ascii GREY
+ {
+ wxUint32 value, size=width*height;
+ for (wxUint32 i=0; i<size; ++i)
+ {
+ value=text_stream.Read32();
+ if ( maxval != 255 )
+ value = (255 * value)/maxval;
+ *ptr++=(unsigned char)value; // R
+ *ptr++=(unsigned char)value; // G
+ *ptr++=(unsigned char)value; // B
+ if ( !buf_stream )
+ {
+ if (verbose) wxLogError(_("PNM: File seems truncated."));
+ return false;
+ }
+ }
+ }
if (c=='3') // Ascii RBG
- {
- wxUint32 value, size=3*width*height;
- for (wxUint32 i=0; i<size; ++i)
- {
- //this is very slow !!!
- //I wonder how we can make any better ?
- value=text_stream.Read32();
- *ptr++=(unsigned char)value;
-
- if (stream.LastError()!=wxSTREAM_NOERROR)
- {
- wxLogError(_T("Loading PNM image : file seems truncated."));
- return FALSE;
- }
- }
- }
- if (c=='6') // Raw RGB
- stream.Read( ptr, 3*width*height );
-
- image->SetMask( FALSE );
-
- return (stream.LastError()==wxStream_NOERROR || stream.LastError()==wxStream_EOF);
+ {
+ wxUint32 value, size=3*width*height;
+ for (wxUint32 i=0; i<size; ++i)
+ {
+ //this is very slow !!!
+ //I wonder how we can make any better ?
+ value=text_stream.Read32();
+ if ( maxval != 255 )
+ value = (255 * value)/maxval;
+ *ptr++=(unsigned char)value;
+
+ if ( !buf_stream )
+ {
+ if (verbose) wxLogError(_("PNM: File seems truncated."));
+ return false;
+ }
+ }
+ }
+ if (c=='5') // Raw GREY
+ {
+ wxUint32 size=width*height;
+ unsigned char value;
+ for (wxUint32 i=0; i<size; ++i)
+ {
+ buf_stream.Read(&value,1);
+ if ( maxval != 255 )
+ value = (255 * value)/maxval;
+ *ptr++=value; // R
+ *ptr++=value; // G
+ *ptr++=value; // B
+ if ( !buf_stream )
+ {
+ if (verbose) wxLogError(_("PNM: File seems truncated."));
+ return false;
+ }
+ }
+ }
+
+ if ( c=='6' ) // Raw RGB
+ {
+ buf_stream.Read(ptr, 3*width*height);
+ if ( maxval != 255 )
+ {
+ for ( unsigned i = 0; i < 3*width*height; i++ )
+ ptr[i] = (255 * ptr[i])/maxval;
+ }
+ }
+
+ image->SetMask( false );
+
+ const wxStreamError err = buf_stream.GetLastError();
+ return err == wxSTREAM_NO_ERROR || err == wxSTREAM_EOF;
}
bool wxPNMHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool WXUNUSED(verbose) )
{
wxTextOutputStream text_stream(stream);
-
- //text_stream << "P6" << endl
- //<< image->GetWidth() << " " << image->GetHeight() << endl
+
+ //text_stream << "P6" << endl
+ //<< image->GetWidth() << " " << image->GetHeight() << endl
//<< "255" << endl;
- text_stream << "P6\n" << image->GetWidth() << " " << image->GetHeight() << "\n255\n";
+ text_stream << wxT("P6\n") << image->GetWidth() << wxT(" ") << image->GetHeight() << wxT("\n255\n");
stream.Write(image->GetData(),3*image->GetWidth()*image->GetHeight());
- return (stream.LastError()==wxStream_NOERROR);
+ return stream.IsOk();
}
-bool wxPNMHandler::CanRead( wxInputStream& stream )
+bool wxPNMHandler::DoCanRead( wxInputStream& stream )
{
- return FALSE; // VS - temporary - FIXME
+ Skip_Comment(stream);
+
+ if ( stream.GetC() == 'P' )
+ {
+ switch ( stream.GetC() )
+ {
+ case '2': // ASCII Grey
+ case '3': // ASCII RGB
+ case '5': // RAW Grey
+ case '6': // RAW RGB
+ return true;
+ }
+ }
+
+ return false;
}
#endif // wxUSE_STREAMS
-
+#endif // wxUSE_IMAGE && wxUSE_PNM