]> git.saurik.com Git - wxWidgets.git/blob - src/common/imagpnm.cpp
Make public headers compatible with Objective-C++ with ARC.
[wxWidgets.git] / src / common / imagpnm.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/imagpnm.cpp
3 // Purpose: wxImage PNM handler
4 // Author: Sylvain Bougnoux
5 // Copyright: (c) Sylvain Bougnoux
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 // For compilers that support precompilation, includes "wx.h".
10 #include "wx/wxprec.h"
11
12 #ifdef __BORLANDC__
13 #pragma hdrstop
14 #endif
15
16 #if wxUSE_IMAGE && wxUSE_PNM
17
18 #include "wx/imagpnm.h"
19
20 #ifndef WX_PRECOMP
21 #include "wx/intl.h"
22 #include "wx/log.h"
23 #endif
24
25 #include "wx/txtstrm.h"
26
27 //-----------------------------------------------------------------------------
28 // wxBMPHandler
29 //-----------------------------------------------------------------------------
30
31 IMPLEMENT_DYNAMIC_CLASS(wxPNMHandler,wxImageHandler)
32
33 #if wxUSE_STREAMS
34
35 void Skip_Comment(wxInputStream &stream)
36 {
37 wxTextInputStream text_stream(stream);
38
39 if (stream.Peek()==wxT('#'))
40 {
41 text_stream.ReadLine();
42 Skip_Comment(stream);
43 }
44 }
45
46 bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
47 {
48 wxUint32 width, height;
49 wxUint16 maxval;
50 char c(0);
51
52 image->Destroy();
53
54 /*
55 * Read the PNM header
56 */
57
58 wxBufferedInputStream buf_stream(stream);
59 wxTextInputStream text_stream(buf_stream);
60
61 Skip_Comment(buf_stream);
62 if (buf_stream.GetC()==wxT('P')) c=buf_stream.GetC();
63
64 switch (c)
65 {
66 case wxT('2'): // ASCII Grey
67 case wxT('3'): // ASCII RGB
68 case wxT('5'): // RAW Grey
69 case wxT('6'): break;
70 default:
71 if (verbose)
72 {
73 wxLogError(_("PNM: File format is not recognized."));
74 }
75 return false;
76 }
77
78 text_stream.ReadLine(); // for the \n
79 Skip_Comment(buf_stream);
80 text_stream >> width >> height ;
81 Skip_Comment(buf_stream);
82 text_stream >> maxval;
83
84 //cout << line << " " << width << " " << height << " " << maxval << endl;
85 image->Create( width, height );
86 unsigned char *ptr = image->GetData();
87 if (!ptr)
88 {
89 if (verbose)
90 {
91 wxLogError( _("PNM: Couldn't allocate memory.") );
92 }
93 return false;
94 }
95
96
97 if (c=='2') // Ascii GREY
98 {
99 wxUint32 value, size=width*height;
100 for (wxUint32 i=0; i<size; ++i)
101 {
102 value=text_stream.Read32();
103 if ( maxval != 255 )
104 value = (255 * value)/maxval;
105 *ptr++=(unsigned char)value; // R
106 *ptr++=(unsigned char)value; // G
107 *ptr++=(unsigned char)value; // B
108 if ( !buf_stream )
109 {
110 if (verbose)
111 {
112 wxLogError(_("PNM: File seems truncated."));
113 }
114 return false;
115 }
116 }
117 }
118 if (c=='3') // Ascii RBG
119 {
120 wxUint32 value, size=3*width*height;
121 for (wxUint32 i=0; i<size; ++i)
122 {
123 //this is very slow !!!
124 //I wonder how we can make any better ?
125 value=text_stream.Read32();
126 if ( maxval != 255 )
127 value = (255 * value)/maxval;
128 *ptr++=(unsigned char)value;
129
130 if ( !buf_stream )
131 {
132 if (verbose)
133 {
134 wxLogError(_("PNM: File seems truncated."));
135 }
136 return false;
137 }
138 }
139 }
140 if (c=='5') // Raw GREY
141 {
142 wxUint32 size=width*height;
143 unsigned char value;
144 for (wxUint32 i=0; i<size; ++i)
145 {
146 buf_stream.Read(&value,1);
147 if ( maxval != 255 )
148 value = (255 * value)/maxval;
149 *ptr++=value; // R
150 *ptr++=value; // G
151 *ptr++=value; // B
152 if ( !buf_stream )
153 {
154 if (verbose)
155 {
156 wxLogError(_("PNM: File seems truncated."));
157 }
158 return false;
159 }
160 }
161 }
162
163 if ( c=='6' ) // Raw RGB
164 {
165 buf_stream.Read(ptr, 3*width*height);
166 if ( maxval != 255 )
167 {
168 for ( unsigned i = 0; i < 3*width*height; i++ )
169 ptr[i] = (255 * ptr[i])/maxval;
170 }
171 }
172
173 image->SetMask( false );
174
175 const wxStreamError err = buf_stream.GetLastError();
176 return err == wxSTREAM_NO_ERROR || err == wxSTREAM_EOF;
177 }
178
179 bool wxPNMHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool WXUNUSED(verbose) )
180 {
181 wxTextOutputStream text_stream(stream);
182
183 //text_stream << "P6" << endl
184 //<< image->GetWidth() << " " << image->GetHeight() << endl
185 //<< "255" << endl;
186 text_stream << wxT("P6\n") << image->GetWidth() << wxT(" ") << image->GetHeight() << wxT("\n255\n");
187 stream.Write(image->GetData(),3*image->GetWidth()*image->GetHeight());
188
189 return stream.IsOk();
190 }
191
192 bool wxPNMHandler::DoCanRead( wxInputStream& stream )
193 {
194 Skip_Comment(stream);
195
196 // it's ok to modify the stream position here
197 if ( stream.GetC() == 'P' )
198 {
199 switch ( stream.GetC() )
200 {
201 case '2': // ASCII Grey
202 case '3': // ASCII RGB
203 case '5': // RAW Grey
204 case '6': // RAW RGB
205 return true;
206 }
207 }
208
209 return false;
210 }
211
212
213 #endif // wxUSE_STREAMS
214
215 #endif // wxUSE_IMAGE && wxUSE_PNM