1 |
william |
31 |
///////////////////////////////////////////////////////////////////////////// |
2 |
|
|
// Name: src/common/imagpnm.cpp |
3 |
|
|
// Purpose: wxImage PNM handler |
4 |
|
|
// Author: Sylvain Bougnoux |
5 |
|
|
// RCS-ID: $Id: imagpnm.cpp 46311 2007-06-03 22:14:32Z VZ $ |
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 |