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