]> git.saurik.com Git - wxWidgets.git/blob - src/common/imagpnm.cpp
fixed 3 infinite loops -- the person who tested this code must have had a lot of...
[wxWidgets.git] / src / common / imagpnm.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: imagpnm.cpp
3 // Purpose: wxImage PNM handler
4 // Author: Sylvain Bougnoux
5 // RCS-ID: $Id$
6 // Copyright: (c) Sylvain Bougnoux
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 #ifdef __GNUG__
11 #pragma implementation "imagpnm.h"
12 #endif
13
14 // For compilers that support precompilation, includes "wx.h".
15 #include "wx/wxprec.h"
16
17 #ifdef __BORLANDC__
18 #pragma hdrstop
19 #endif
20
21 #ifndef WX_PRECOMP
22 # include "wx/setup.h"
23 #endif
24
25 #if wxUSE_IMAGE && wxUSE_PNM
26
27 #include "wx/imagpnm.h"
28 #include "wx/log.h"
29 #include "wx/intl.h"
30 #include "wx/txtstrm.h"
31
32 //-----------------------------------------------------------------------------
33 // wxBMPHandler
34 //-----------------------------------------------------------------------------
35
36 IMPLEMENT_DYNAMIC_CLASS(wxPNMHandler,wxImageHandler)
37
38 #if wxUSE_STREAMS
39
40 void Skip_Comment(wxInputStream &stream)
41 {
42 wxTextInputStream text_stream(stream);
43
44 if (stream.Peek()==wxT('#'))
45 {
46 text_stream.ReadLine();
47 Skip_Comment(stream);
48 }
49 }
50
51 bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
52 {
53 wxUint32 width, height;
54 wxUint16 maxval;
55 char c(0);
56
57 image->Destroy();
58
59 /*
60 * Read the PNM header
61 */
62
63 wxBufferedInputStream buf_stream(stream);
64 wxTextInputStream text_stream(buf_stream);
65
66 Skip_Comment(buf_stream);
67 if (buf_stream.GetC()==wxT('P')) c=buf_stream.GetC();
68
69 switch (c)
70 {
71 case wxT('2'):
72 if (verbose) wxLogError(_("Loading Grey Ascii PNM image is not yet implemented."));
73 return FALSE;
74 case wxT('5'):
75 if (verbose) wxLogError(_("Loading Grey Raw PNM image is not yet implemented."));
76 return FALSE;
77 case wxT('3'):
78 case wxT('6'): break;
79 default:
80 if (verbose) wxLogError(_("PNM: File format is not recognized."));
81 return FALSE;
82 }
83
84 text_stream.ReadLine(); // for the \n
85 Skip_Comment(buf_stream);
86 text_stream >> width >> height ;
87 Skip_Comment(buf_stream);
88 text_stream >> maxval;
89
90 //cout << line << " " << width << " " << height << " " << maxval << endl;
91 image->Create( width, height );
92 unsigned char *ptr = image->GetData();
93 if (!ptr)
94 {
95 if (verbose)
96 wxLogError( _("PNM: Couldn't allocate memory.") );
97 return FALSE;
98 }
99
100 if (c=='3') // Ascii RBG
101 {
102 wxUint32 value, size=3*width*height;
103 for (wxUint32 i=0; i<size; ++i)
104 {
105 //this is very slow !!!
106 //I wonder how we can make any better ?
107 value=text_stream.Read32();
108 *ptr++=(unsigned char)value;
109
110 if ( !buf_stream )
111 {
112 if (verbose) wxLogError(_("PNM: File seems truncated."));
113 return FALSE;
114 }
115 }
116 }
117 if (c=='6') // Raw RGB
118 buf_stream.Read( ptr, 3*width*height );
119
120 image->SetMask( FALSE );
121
122 const wxStreamError err = buf_stream.GetLastError();
123 return err == wxSTREAM_NO_ERROR || err == wxSTREAM_EOF;
124 }
125
126 bool wxPNMHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool WXUNUSED(verbose) )
127 {
128 wxTextOutputStream text_stream(stream);
129
130 //text_stream << "P6" << endl
131 //<< image->GetWidth() << " " << image->GetHeight() << endl
132 //<< "255" << endl;
133 text_stream << wxT("P6\n") << image->GetWidth() << wxT(" ") << image->GetHeight() << wxT("\n255\n");
134 stream.Write(image->GetData(),3*image->GetWidth()*image->GetHeight());
135
136 return stream.IsOk();
137 }
138
139 bool wxPNMHandler::DoCanRead( wxInputStream& stream )
140 {
141 Skip_Comment(stream);
142
143 if ( stream.GetC() == 'P' )
144 {
145 switch (stream.GetC())
146 {
147 case '3':
148 case '6':
149 return TRUE;
150 }
151 }
152
153 return FALSE;
154 }
155
156
157 #endif // wxUSE_STREAMS
158
159 #endif // wxUSE_PNM