]> git.saurik.com Git - wxWidgets.git/blob - src/common/imagpnm.cpp
GTK2: gtk_idle_add_priority -> g_idle_add_full; gtk_idle_remove -> g_source_remove
[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 #ifndef WX_PRECOMP
18 #endif
19
20 #if wxUSE_IMAGE && wxUSE_PNM
21
22 #include "wx/imagpnm.h"
23 #include "wx/log.h"
24 #include "wx/intl.h"
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) wxLogError(_("PNM: File format is not recognized."));
72 return false;
73 }
74
75 text_stream.ReadLine(); // for the \n
76 Skip_Comment(buf_stream);
77 text_stream >> width >> height ;
78 Skip_Comment(buf_stream);
79 text_stream >> maxval;
80
81 //cout << line << " " << width << " " << height << " " << maxval << endl;
82 image->Create( width, height );
83 unsigned char *ptr = image->GetData();
84 if (!ptr)
85 {
86 if (verbose)
87 wxLogError( _("PNM: Couldn't allocate memory.") );
88 return false;
89 }
90
91
92 if (c=='2') // Ascii GREY
93 {
94 wxUint32 value, size=width*height;
95 for (wxUint32 i=0; i<size; ++i)
96 {
97 value=text_stream.Read32();
98 *ptr++=(unsigned char)value; // R
99 *ptr++=(unsigned char)value; // G
100 *ptr++=(unsigned char)value; // B
101 if ( !buf_stream )
102 {
103 if (verbose) wxLogError(_("PNM: File seems truncated."));
104 return false;
105 }
106 }
107 }
108 if (c=='3') // Ascii RBG
109 {
110 wxUint32 value, size=3*width*height;
111 for (wxUint32 i=0; i<size; ++i)
112 {
113 //this is very slow !!!
114 //I wonder how we can make any better ?
115 value=text_stream.Read32();
116 *ptr++=(unsigned char)value;
117
118 if ( !buf_stream )
119 {
120 if (verbose) wxLogError(_("PNM: File seems truncated."));
121 return false;
122 }
123 }
124 }
125 if (c=='5') // Raw GREY
126 {
127 wxUint32 size=width*height;
128 unsigned char value;
129 for (wxUint32 i=0; i<size; ++i)
130 {
131 buf_stream.Read(&value,1);
132 *ptr++=value; // R
133 *ptr++=value; // G
134 *ptr++=value; // B
135 if ( !buf_stream )
136 {
137 if (verbose) wxLogError(_("PNM: File seems truncated."));
138 return false;
139 }
140 }
141 }
142 if (c=='6') // Raw RGB
143 buf_stream.Read( ptr, 3*width*height );
144
145 image->SetMask( false );
146
147 const wxStreamError err = buf_stream.GetLastError();
148 return err == wxSTREAM_NO_ERROR || err == wxSTREAM_EOF;
149 }
150
151 bool wxPNMHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool WXUNUSED(verbose) )
152 {
153 wxTextOutputStream text_stream(stream);
154
155 //text_stream << "P6" << endl
156 //<< image->GetWidth() << " " << image->GetHeight() << endl
157 //<< "255" << endl;
158 text_stream << wxT("P6\n") << image->GetWidth() << wxT(" ") << image->GetHeight() << wxT("\n255\n");
159 stream.Write(image->GetData(),3*image->GetWidth()*image->GetHeight());
160
161 return stream.IsOk();
162 }
163
164 bool wxPNMHandler::DoCanRead( wxInputStream& stream )
165 {
166 Skip_Comment(stream);
167
168 if ( stream.GetC() == 'P' )
169 {
170 switch ( stream.GetC() )
171 {
172 case '2': // ASCII Grey
173 case '3': // ASCII RGB
174 case '5': // RAW Grey
175 case '6': // RAW RGB
176 return true;
177 }
178 }
179
180 return false;
181 }
182
183
184 #endif // wxUSE_STREAMS
185
186 #endif // wxUSE_PNM