/[public]/psiconv/trunk/lib/psiconv/parse_image.c
ViewVC logotype

Annotation of /psiconv/trunk/lib/psiconv/parse_image.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 25 - (hide annotations)
Sat Oct 30 22:28:54 1999 UTC (24 years, 5 months ago) by frodo
File MIME type: text/plain
File size: 16942 byte(s)
(Frodo) Parsing of both MBM and Sketch files finished and correct!

To do:
  * Need to ask ImageMagick what output formats are available;
  * Need to display those formats in --help, and understand them on the
    command-line;
  * Need to generate the correct type of file;
  * Need to take a look at some special Sketch options (size, cuts, etc)
  * Sometimes, the file seems to be negative. Probably an ImageMagick
    problem.
  * Need to handle several images in one file elegantly

1 frodo 10 /*
2     parse_image.c - Part of psiconv, a PSION 5 file formats converter
3     Copyright (c) 1999 Frodo Looijaard <frodol@dds.nl>
4    
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9    
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     GNU General Public License for more details.
14    
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18     */
19    
20     #include "config.h"
21     #include <stdlib.h>
22    
23     #include "data.h"
24     #include "parse_routines.h"
25    
26 frodo 12 int psiconv_parse_mbm_jumptable_section(const psiconv_buffer buf,int lev,
27     psiconv_u32 off, int *length,
28     psiconv_mbm_jumptable_section *result)
29     {
30     int res = 0;
31     int len = 0;
32     psiconv_u32 listlen,temp;
33     int i;
34    
35     psiconv_progress(lev+1,off+len,"Going to read the mbm jumptable section");
36     (*result) = psiconv_list_new(sizeof(psiconv_u32));
37    
38     psiconv_progress(lev+2,off+len,"Going to read the list length");
39     listlen = psiconv_read_u32(buf,lev+2,off+len);
40     psiconv_debug(lev+2,off+len,"List length: %08x",listlen);
41     len += 4;
42    
43     psiconv_progress(lev+2,off+len,"Going to read the list");
44     for (i = 0; i < listlen; i++) {
45     temp = psiconv_read_u32(buf,lev+2,off+len);
46     psiconv_list_add(*result,&temp);
47     psiconv_debug(lev+3,off+len,"Offset: %08x",temp);
48     len += 4;
49     }
50    
51     if (length)
52     *length = len;
53    
54     psiconv_progress(lev+1,off+len-1,"End of mbm jumptable section "
55 frodo 13 "(total length: %08x)", len);
56 frodo 12
57     return res;
58     }
59    
60 frodo 25 static int decode_byte(int lev, psiconv_u32 off,
61     psiconv_paint_data_section data, int *pixelnr,
62     psiconv_u8 byte, int bits_per_pixel, int linelen,
63     int *linepos,int picsize)
64     {
65     int mask = (bits_per_pixel << 1) -1;
66     int i;
67     if (*linepos < (data->xsize + (8/bits_per_pixel) - 1) / (8/bits_per_pixel))
68     for (i = 0; i < 8/bits_per_pixel; i ++) {
69     if ((i != 0) && ((*pixelnr % (data->xsize)) == 0)) {
70     psiconv_debug(lev+1,off,"Skipping padding: %02x",byte);
71     i = 8;
72     } else if (*pixelnr >= picsize) {
73     psiconv_warn(lev+1,off,"Corrupted picture data!");
74     psiconv_debug(lev+1,off,"Trying to write a pixel too far");
75     return -1;
76     } else {
77     data->red[*pixelnr] = data->green[*pixelnr] = data->blue[*pixelnr] =
78     ((float) (byte & mask)) / ((1 << bits_per_pixel) -1);
79     psiconv_debug(lev+1,off,"Pixel %04x: (%04x,%04x) value %02x, color %f",
80     *pixelnr,*pixelnr % data->xsize,*pixelnr / data->xsize, byte&mask, data->red[*pixelnr]);
81     byte = byte >> bits_per_pixel;
82     (*pixelnr) ++;
83     }
84     }
85     else
86     psiconv_debug(lev+1,off,"Skipping padding byte");
87     (*linepos) ++;
88     if (*linepos == linelen)
89     *linepos = 0;
90     return 0;
91     }
92    
93    
94 frodo 10 int psiconv_parse_paint_data_section(const psiconv_buffer buf,int lev,
95     psiconv_u32 off, int *length,
96     psiconv_paint_data_section *result)
97     {
98     int res = 0;
99     int len = 0;
100 frodo 12 int read_err = 0;
101 frodo 13 psiconv_u32 size,offset,picsize,temp,datasize,pixelnr,datanr,linelen;
102 frodo 11 psiconv_u8 marker;
103 frodo 25 int i,leng;
104     psiconv_u32 bits_per_pixel,compression;
105     int linepos = 0;
106 frodo 10
107     psiconv_progress(lev+1,off,"Going to read a paint data section");
108     (*result) = malloc(sizeof(**result));
109    
110     psiconv_progress(lev+2,off+len,"Going to read section size");
111     size = psiconv_read_u32(buf,lev+2,off+len);
112     psiconv_debug(lev+2,off+len,"Section size: %08x",size);
113     len += 4;
114    
115     psiconv_progress(lev+2,off+len,"Going to read pixel data offset");
116     offset = psiconv_read_u32(buf,lev+2,off+len);
117 frodo 13 if (offset != 0x28) {
118 frodo 10 psiconv_warn(lev+2,off+len,
119     "Paint data section data offset has unexpected value");
120     psiconv_debug(lev+2,off+len,
121     "Data offset: read %08x, expected %08x",offset,0x28);
122 frodo 12 res = -1;
123 frodo 10 }
124     len += 4;
125    
126     psiconv_progress(lev+2,off+len,"Going to read picture X size");
127     (*result)->xsize = psiconv_read_u32(buf,lev+2,off+len);
128     psiconv_debug(lev+2,off+len,"Picture X size: %08x:",(*result)->xsize);
129     len += 4;
130    
131     psiconv_progress(lev+2,off+len,"Going to read picture Y size");
132     (*result)->ysize = psiconv_read_u32(buf,lev+2,off+len);
133     psiconv_debug(lev+2,off+len,"Picture Y size: %08x:",(*result)->ysize);
134     len += 4;
135    
136 frodo 25 picsize = (*result)->ysize * (*result)->xsize;
137 frodo 10
138 frodo 25 psiconv_progress(lev+2,off+len,"Going to read the real picture x size");
139     (*result)->pic_xsize = psiconv_read_length(buf,lev+2,off+len,&leng);
140     psiconv_debug(lev+2,off+len,"Picture x size: %f",(*result)->pic_xsize);
141     len += leng;
142    
143     psiconv_progress(lev+2,off+len,"Going to read the real picture y size");
144     (*result)->pic_ysize = psiconv_read_length(buf,lev+2,off+len,&leng);
145     psiconv_debug(lev+2,off+len,"Picture y size: %f",(*result)->pic_ysize);
146     len += leng;
147    
148     psiconv_progress(lev+2,off+len,"Going to read the number of bits per pixel");
149     bits_per_pixel=psiconv_read_u32(buf,lev+2,off+len);
150     if (bits_per_pixel > 8) {
151     psiconv_warn(lev+2,off+len,"Picture has too many colors");
152     psiconv_debug(lev+2,off+len,"Read %d colorbits",bits_per_pixel);
153     res = -1;
154     bits_per_pixel = 2;
155     }
156     psiconv_debug(lev+2,off+len,"Bits per pixel: %d",bits_per_pixel);
157     len += 4;
158    
159     for (i = 0 ; i < 2; i++) {
160 frodo 10 temp = psiconv_read_u32(buf,lev+2,off+len);
161 frodo 25 if (temp != 00) {
162 frodo 10 psiconv_warn(lev+2,off+len,
163     "Paint data section prologue has unknown values");
164     psiconv_debug(lev+2,off+len,
165 frodo 25 "offset %02x: read %08x, expected %08x",i,temp, 0x00);
166 frodo 12 res = -1;
167 frodo 10 }
168     len += 4;
169     }
170 frodo 25
171     psiconv_progress(lev+2,off+len,
172     "Going to read whether RLE compression is used");
173     compression=psiconv_read_u32(buf,lev+2,off+len);
174     if (compression > 1) {
175     psiconv_warn(lev+2,off+len,"Paint data section has unknown "
176     "compression type, assuming RLE");
177     psiconv_debug(lev+2,off+len,"Read compression type %d",compression);
178     compression = 1;
179     }
180     psiconv_debug(lev+2,off+len,"Compression: %s",compression?"RLE":"none");
181 frodo 10
182     (*result)->red = malloc(sizeof(float) * picsize);
183     (*result)->green = malloc(sizeof(float) * picsize);
184     (*result)->blue = malloc(sizeof(float) * picsize);
185     len = offset;
186     datasize = size - len;
187    
188 frodo 11 psiconv_progress(lev+2,off+len,"Going to read the pixel data");
189 frodo 10 pixelnr = 0;
190     datanr = 0;
191 frodo 25 if (!compression) {
192     linelen = datasize / (*result)->ysize;
193     psiconv_debug(lev+3,off+len,"Line length: %04x bytes",linelen);
194     while((datanr < datasize)) {
195     temp = psiconv_read_u8(buf,lev+2,off+len+datanr);
196     if (decode_byte(lev+3,off+len+datanr,*result,&pixelnr,temp,bits_per_pixel,
197     linelen,&linepos,picsize)) {
198 frodo 15 read_err = 1;
199 frodo 12 res = -1;
200 frodo 25 break;
201     }
202     datanr++;
203     }
204     } else {
205     psiconv_progress(lev+2,off+len,"First pass: determining line length");
206     datanr = 0;
207     i = 0;
208     while (datanr < datasize) {
209     marker = psiconv_read_u8(buf,lev+3,off+len+datanr);
210     if (marker >= 0x80) {
211     datanr += 0x100 - marker + 1;
212     i += 0x100 - marker;
213 frodo 10 } else {
214 frodo 25 datanr += 2;
215     i += marker + 1;
216     }
217     }
218     linelen = i / (*result)->ysize;
219     datanr=0;
220     psiconv_debug(lev+2,off+len,"Linelen: %04x bytes",linelen);
221     while((datanr < datasize)) {
222     marker = psiconv_read_u8(buf,lev+3,off+len+datanr);
223     psiconv_debug(lev+3,off+len+datanr,
224     "Pixelnr %08x, Datanr %08x: Read marker %02x",
225     pixelnr,datanr,marker);
226     datanr ++;
227     if (marker >= 0x80) {
228     /* 0x100 - marker bytes of data follow */
229     for (i = 0; i < 0x100-marker; i++,datanr++) {
230     if (datanr >= datasize) {
231 frodo 15 psiconv_warn(lev+3,off+len+datanr,"Corrupted picture data");
232     psiconv_debug(lev+3,off+len+datanr,
233     "Picsize: %08x, Datasize: %08x, Pixelnr: %08x,"
234     "Datanr: %08x, marker: %02x",picsize,datasize,pixelnr,
235     datanr,marker);
236     read_err = 1;
237     res = -1;
238 frodo 25 break;
239     }
240     temp = psiconv_read_u8(buf,lev+2,off+len+datanr);
241     if (decode_byte(lev+2,off+len+datanr,*result,&pixelnr,temp,
242     bits_per_pixel,linelen,&linepos,picsize)) {
243     res = -1;
244     read_err = 1;
245     break;
246 frodo 15 }
247 frodo 25 }
248     } else {
249     if (datanr >= datasize) {
250     psiconv_warn(lev+3,off+len+datanr,"Corrupted picture data");
251     psiconv_debug(lev+3,off+len+datanr,
252     "Picsize: %08x, Datasize: %08x, Pixelnr: %08x,"
253     "Datanr: %08x, marker: %02x",picsize,datasize,pixelnr,
254     datanr,marker);
255     read_err = 1;
256     res = -1;
257     } else {
258     temp = psiconv_read_u8(buf,lev+3,off+len+datanr);
259     for (i = 0; i <= marker; i++) {
260     if (decode_byte(lev+2,off+len+datanr,*result,&pixelnr,temp,
261     bits_per_pixel,linelen,&linepos,picsize)) {
262     read_err = 1;
263     res = -1;
264     break;
265     }
266     }
267     datanr ++;
268     }
269 frodo 10 }
270     }
271     }
272 frodo 25
273     if (linepos >= ((*result)->xsize + (8/bits_per_pixel) - 1) /
274     (8/bits_per_pixel))
275     datanr += (linelen - linepos);
276    
277 frodo 12 if (!read_err && ((datanr != datasize) || (pixelnr != picsize))) {
278     psiconv_warn(lev+2,off+len,"Corrupted picture data!");
279     psiconv_debug(lev+3,off+len+datanr,
280     "Picsize: %08x, Datasize: %08x, Pixelnr: %08x,"
281     "Datanr: %08x",picsize,datasize,pixelnr,datanr);
282     res = -1;
283     }
284    
285 frodo 10 len += datanr;
286    
287     if (length)
288     *length = len;
289    
290     psiconv_progress(lev+1,off+len-1,"End of paint data section "
291 frodo 13 "(total length: %08x)", len);
292 frodo 10
293     return res;
294     }
295    
296 frodo 24 int psiconv_parse_sketch_section(const psiconv_buffer buf, int lev,
297     psiconv_u32 off, int *length, int is_object,
298     psiconv_sketch_section *result)
299     {
300     int res=0;
301     int len=0;
302     psiconv_u32 temp;
303     int leng;
304     int i;
305    
306     psiconv_progress(lev+1,off,"Going to read the sketch section");
307     *result = malloc(sizeof(**result));
308    
309     if (!is_object) {
310     psiconv_progress(lev+2,off+len,"Going to read the form hor. size");
311     (*result)->form_xsize = psiconv_read_u16(buf,lev+2,off + len);
312     psiconv_debug(lev+2,off+len,"Form hor. size: %04x",
313     (*result)->form_xsize);
314     len += 0x02;
315     psiconv_progress(lev+2,off+len,"Going to read the form ver. size");
316     (*result)->form_ysize = psiconv_read_u16(buf,lev+2,off + len);
317     psiconv_debug(lev+2,off+len,"Form ver. size: %04x",
318     (*result)->form_ysize);
319     len += 0x02;
320     psiconv_progress(lev+2,off+len,"Going to read the picture hor. offset");
321     (*result)->picture_x_offset = psiconv_read_u16(buf,lev+2,off + len);
322     psiconv_debug(lev+2,off+len,"Picture hor. offset: %04x",
323     (*result)->picture_x_offset);
324     len += 0x02;
325     psiconv_progress(lev+2,off+len,"Going to read the picture ver. offset");
326     (*result)->picture_y_offset = psiconv_read_u16(buf,lev+2,off + len);
327     psiconv_debug(lev+2,off+len,"Picture ver. offset: %04x",
328     (*result)->picture_y_offset);
329     len += 0x02;
330     psiconv_progress(lev+2,off+len,"Going to skip 5 words of zeros");
331     for (i = 0; i < 5; i++) {
332     temp = psiconv_read_u16(buf,lev+2,off+len);
333     if (temp != 0) {
334     psiconv_warn(lev+2,off+len,
335     "Unexpected value in sketch section preamble");
336     psiconv_debug(lev+2,off+len,"Word %d: Read %04x, expected %04x",i,
337     temp,0);
338     res = -1;
339     }
340     off += 0x02;
341     }
342     } else {
343     psiconv_progress(lev+2,off+len,"Going to read the displayed hor. size");
344     (*result)->picture_xsize = psiconv_read_u16(buf,lev+2,off + len);
345     psiconv_debug(lev+2,off+len,"Displayed hor. size: %04x",
346     (*result)->picture_xsize);
347     len += 0x02;
348     psiconv_progress(lev+2,off+len,"Going to read the displayed ver. size");
349     (*result)->picture_ysize = psiconv_read_u16(buf,lev+2,off + len);
350     psiconv_debug(lev+2,off+len,"Displayed ver. size: %04x",
351     (*result)->picture_ysize);
352     len += 0x02;
353    
354     psiconv_progress(lev+2,off+len,"Going to skip 2 words of zeros");
355     for (i = 0; i < 2; i++) {
356     temp = psiconv_read_u16(buf,lev+2,off+len);
357     if (temp != 0) {
358     psiconv_warn(lev+2,off+len,
359     "Unexpected value in sketch section preamble");
360     psiconv_debug(lev+2,off+len,"Word %d: Read %04x, expected %04x",i,
361     temp,0);
362     res = -1;
363     }
364     off += 0x02;
365     }
366     psiconv_progress(lev+2,off+len,"Going to read the picture hor. offset");
367     (*result)->picture_x_offset = psiconv_read_u16(buf,lev+2,off + len);
368     psiconv_debug(lev+2,off+len,"Picture hor. offset: %04x",
369     (*result)->picture_x_offset);
370     len += 0x02;
371     psiconv_progress(lev+2,off+len,"Going to read the picture ver. offset");
372     (*result)->picture_y_offset = psiconv_read_u16(buf,lev+2,off + len);
373     psiconv_debug(lev+2,off+len,"Picture ver. offset: %04x",
374     (*result)->picture_y_offset);
375     len += 0x02;
376     psiconv_progress(lev+2,off+len,"Going to read the form hor. size");
377     (*result)->form_xsize = psiconv_read_u16(buf,lev+2,off + len);
378     psiconv_debug(lev+2,off+len,"Form hor. size: %04x",
379     (*result)->form_xsize);
380     len += 0x02;
381     psiconv_progress(lev+2,off+len,"Going to read the form ver. size");
382     (*result)->form_ysize = psiconv_read_u16(buf,lev+2,off + len);
383     psiconv_debug(lev+2,off+len,"Form ver. size: %04x",
384     (*result)->form_ysize);
385     len += 0x02;
386     psiconv_progress(lev+2,off+len,"Going to skip 1 zero word");
387     temp = psiconv_read_u16(buf,lev+2,off+len);
388     if (temp != 0) {
389     psiconv_warn(lev+2,off+len,
390     "Unexpected value in sketch section preamble");
391     psiconv_debug(lev+2,off+len,"Read %04x, expected %04x",i, temp,0);
392     res = -1;
393     }
394     off += 0x02;
395     }
396    
397     psiconv_progress(lev+2,off+len,"Going to read the picture data");
398     res |= psiconv_parse_paint_data_section(buf,lev+2,off+len,&leng,
399     &((*result)->picture));
400     off += leng;
401     if (!is_object) {
402     (*result)->picture_xsize = (*result)->picture->xsize;
403     (*result)->picture_ysize = (*result)->picture->ysize;
404     }
405    
406     psiconv_progress(lev+2,off+len,"Going to read the hor. magnification");
407     (*result)->magnification_x = psiconv_read_u16(buf,lev+2,off + len) / 1000.0;
408     psiconv_debug(lev+2,off+len,"Form hor. magnification: %f",
409     (*result)->magnification_x);
410     len += 0x02;
411     psiconv_progress(lev+2,off+len,"Going to read the ver. magnification");
412     (*result)->magnification_y = psiconv_read_u16(buf,lev+2,off + len) / 1000.0;
413     psiconv_debug(lev+2,off+len,"Form ver. magnification: %f",
414     (*result)->magnification_y);
415     len += 0x02;
416    
417     psiconv_progress(lev+2,off+len,"Going to read the left cut");
418     temp = psiconv_read_u32(buf,lev+2,off + len);
419     (*result)->cut_left = (temp * 6.0) / (*result)->picture_xsize;
420     psiconv_debug(lev+2,off+len,"Left cut: raw %08x, real: %f",
421     temp,(*result)->cut_left);
422     len += 0x04;
423     psiconv_progress(lev+2,off+len,"Going to read the right cut");
424     temp = psiconv_read_u32(buf,lev+2,off + len);
425     (*result)->cut_right = (temp * 6.0) / (*result)->picture_xsize;
426     psiconv_debug(lev+2,off+len,"Right cut: raw %08x, real: %f",
427     temp,(*result)->cut_right);
428     len += 0x04;
429     psiconv_progress(lev+2,off+len,"Going to read the top cut");
430     temp = psiconv_read_u32(buf,lev+2,off + len);
431     (*result)->cut_top = (temp * 6.0) / (*result)->picture_ysize;
432     psiconv_debug(lev+2,off+len,"Top cut: raw %08x, real: %f",
433     temp,(*result)->cut_top);
434     len += 0x04;
435     psiconv_progress(lev+2,off+len,"Going to read the bottom cut");
436     temp = psiconv_read_u32(buf,lev+2,off + len);
437     (*result)->cut_bottom = (temp * 6.0) / (*result)->picture_ysize;
438     psiconv_debug(lev+2,off+len,"Bottom cut: raw %08x, real: %f",
439     temp,(*result)->cut_bottom);
440     len += 0x04;
441    
442     if (length)
443     *length = len;
444    
445     psiconv_progress(lev,off+len-1,
446     "End of sketch section (total length: %08x)", len);
447    
448     return res;
449     }
450    

frodo@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26