| Bsoft 2.0.5 Bernard's software package

rwPNM.cpp
Go to the documentation of this file.
1
9 #include "rwPNM.h"
10 #include "utilities.h"
11 #include <fstream>
12
13 // Declaration of global variables
14 extern int verbose; // Level of output to the screen
15
16 char* pnm_next_item(char* aptr)
17 {
18 while ( !isspace(*aptr) ) aptr++; // Skip any initial characters
19
20 while ( isspace(*aptr) ) aptr++; // Skip all white space
21
22 while ( *aptr == '#' ) { // Skip any comments
23 while ( *aptr != '\n' ) aptr++;
24 aptr++;
25 while ( isspace(*aptr) ) aptr++;
26 }
27
28 return aptr;
29 }
30
31 unsigned char* pnm_read_data(ifstream* fimg, Bimage* p)
32 {
33 char aline[MAXLINELEN], *aptr;
34 int n;
35 long i(0), len, v;
36 long imgsize = p->sizeX()*p->sizeY()*p->sizeZ()*p->channels();
37 long x, y, new_x = (p->sizeX()-1)/8 + 1;
38
39 unsigned char* data = p->data_alloc();
40 unsigned short* usdata = (unsigned short *) data;
41
42 fimg->seekg(p->data_offset(), ios_base::cur);
43
44 while ( fimg->getline(aline, MAXLINELEN) && i < imgsize ) {
45 len = strlen(aline);
46 for ( aptr = aline; *aptr != '\n' && aptr < aline + len; ) {
47 if ( sscanf(aptr, "%ld%n", &v, &n) ) {
48 if ( p->data_type() == Bit ) {
49 if ( v ) {
50 x = i%p->sizeX();
51 y = i/p->sizeX();
52 data[y*new_x+x/8] |= 0x80 >> x%8;
53 }
54 } else if ( p->data_type() == UCharacter ) data[i] = v;
55 else usdata[i] = v;
56 i++;
57 }
58 aptr += n;
59 }
60 }
61
62 return data;
63 }
64
79 int readPNM(Bimage* p, int readdata, int img_select)
80 {
81 if ( verbose & VERB_DEBUG )
82 cout << "DEBUG readPNM: Filename = " << p->file_name() << endl;
83
84 p->data_type(UCharacter);
85
86 p->sizeZ(1);
87 p->channels(1);
88
89 string ext(extension(p->file_name()));
90 if ( ext.find("pbm") != string::npos ) p->data_type(Bit);
91 else if ( ext.find("pgm") != string::npos ) p->compound_type(TSimple);
92 else if ( ext.find("ppm") != string::npos ) {
93 p->compound_type(TRGB);
94 p->channels(3);
95 } else {
96 cerr << "Error: File with extension " << ext << " not recognized!" << endl;
97 return -1;
98 }
99
100 ifstream* fimg = new ifstream;
101 fimg->open(p->file_name());
102 if ( fimg->fail() ) return -1;
103
104 if ( verbose & VERB_DEBUG )
105 cout << "DEBUG readPNM: File opened" << endl;
106
107 char aline[MAXLINELEN], *aptr;
108 int magic(0);
109 memset(aline, 0, MAXLINELEN);
110
111 fimg->seekg(0, ios_base::end);
112 int len = fimg->tellg();
113 fimg->seekg(0);
114 if ( verbose & VERB_DEBUG )
115 cout << "DEBUG readPNM: File length = " << len << endl;
116 if ( len > MAXLINELEN ) len = MAXLINELEN;
117
118 if ( !fimg->read(aline, len) ) return -2;
119 sscanf(aline, "P%d", &magic);
120 switch ( magic ) {
121 case 1:
122 case 4: p->data_type(Bit); p->channels(1); break;
123 case 2:
124 case 5: p->compound_type(TSimple); p->channels(1); break;
125 case 3:
126 case 6: p->compound_type(TRGB); p->channels(3); break;
127 default: break;
128 }
129
130 aptr = pnm_next_item(aline);
131 p->sizeX(atoi(aptr));
132 aptr = pnm_next_item(aptr);
133 p->sizeY(atoi(aptr));
134
135 p->page_size(p->size());
136
137 if ( p->data_type() > Bit ) {
138 aptr = pnm_next_item(aptr);
139 if ( atoi(aptr) > UCHAR_MAX ) p->data_type(UShort);
140 }
141
142 while ( !isspace(*aptr) ) aptr++; // Skip any initial characters
143 p->data_offset(aptr + 1 - aline);
144
145 // if ( img_select > -1 ) {
146 // if ( img_select >= p->images() ) img_select = p->images() - 1;
147 // p->images(1);
148 // } else img_select = -1;
149 p->images(1);
150
151
152 if ( !readdata ) {
153 fimg->close();
154 return 0;
155 }
156
157 if ( magic < 4 ) {
158 pnm_read_data(fimg, p);
159 } else {
160 fimg->seekg(p->data_offset(), ios_base::beg);
161 long readsize = p->alloc_size();
162 unsigned char* data = p->data_alloc();
163 fimg->read((char *)data, readsize);
164 }
165
166 fimg->close();
167
168 delete fimg;
169
170 if ( verbose & VERB_DEBUG )
171 cout << "DEBUG readPNM: File read: type = " << magic << endl;
172
173 return 0;
174 }
175
182 int writePNM(Bimage* p)
183 {
184 string ext(extension(p->file_name()));
185
186 if ( ext.find("pbm") != string::npos ) p->change_type(Bit);
187 else if ( ext.find("pgm") != string::npos ) p->color_to_simple();
188
189 if ( p->data_type() > UShort ) p->change_type(UShort);
190 else if ( p->data_type() > UCharacter ) p->change_type(UCharacter);
191
192 ofstream fimg(p->file_name());
193 if ( fimg.fail() ) return -1;
194
195 long n;
196 long imgsize = p->sizeX()*p->sizeY()*p->channels()*p->data_type_size();
197 if ( p->data_type() == Bit ) imgsize = (p->page_size()[0]/8)*p->sizeY();
198 int max = (int) p->maximum();
199 if ( p->data_type() == UShort && max <= UCHAR_MAX ) max = UCHAR_MAX + 1;
200 unsigned char* data = p->data_pointer();
201
202 if ( verbose & VERB_DEBUG )
203 cout << "DEBUG writePNM: datatype=" << p->data_type() << endl;
204
205 for ( n=0; n<p->images(); n++, data += imgsize ) {
206 if ( p->data_type() == Bit ) fimg << "P4" << endl;
207 else if ( p->compound_type() == TSimple ) fimg << "P5" << endl;
208 else if ( p->compound_type() == TRGB ) fimg << "P6" << endl;
209 else cerr << "Error: Compound type " << p->compound_type() << " not supported!" << endl;
210 fimg << p->sizeX() << " " << p->sizeY() << endl;
211 if ( p->data_type() > Bit ) {
212 if ( p->data_type() == UCharacter || p->data_type() == UShort ) fimg << max << endl;
213 else cerr << "Error: Data type " << p->data_type() << " not supported!" << endl;
214 }
215 fimg.write((char *)data, imgsize);
216 }
217
218 fimg.close();
219
220 return 0;
221 }
222
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
extension
string extension(string filename)
Definition: string_util.cpp:32
Bimage::data_type_size
long data_type_size() const
Returns the size of the datatype in bytes.
Definition: Bimage.cpp:1585
utilities.h
Header file for general utilities.
writePNM
int writePNM(Bimage *p)
Writing a PNM type file. A simple image format.
Definition: rwPNM.cpp:182
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
MAXLINELEN
#define MAXLINELEN
Definition: utilities.h:44
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
readPNM
int readPNM(Bimage *p, int readdata, int img_select)
Reading a PNM type file. A simple image format. PBM bit image format. PGM grayscale image format....
Definition: rwPNM.cpp:79
TSimple
Definition: Bimage.h:58
Bimage
General image parameter class.
Definition: Bimage.h:163
Bimage::data_alloc
unsigned char * data_alloc()
Definition: Bimage.h:256
Bimage::maximum
double maximum()
Definition: Bimage.h:535
verbose
int verbose
rwPNM.h
Header file for reading and writing PNM files.
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bimage::data_offset
long data_offset()
Definition: Bimage.h:265
Bimage::channels
long channels()
Definition: Bimage.h:371
TRGB
Definition: Bimage.h:62
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
UCharacter
Definition: utilities.h:149
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
Bit
Definition: utilities.h:148
Bimage::alloc_size
long alloc_size() const
Definition: Bimage.h:252
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
pnm_read_data
unsigned char * pnm_read_data(ifstream *fimg, Bimage *p)
Definition: rwPNM.cpp:31
Bimage::color_to_simple
void color_to_simple()
A color image is converted to a simple image.
Definition: Bimage_color.cpp:94
UShort
Definition: utilities.h:151
Bimage::page_size
Vector3< long > page_size()
Definition: Bimage.h:480
Bimage::images
long images()
Definition: Bimage.h:491
Bimage::sizeY
void sizeY(long ny)
Definition: Bimage.h:378
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
pnm_next_item
char * pnm_next_item(char *aptr)
Definition: rwPNM.cpp:16