/[public]/psiconv/tags/rel-0-9-9/lib/psiconv/generate_image.c
ViewVC logotype

Diff of /psiconv/tags/rel-0-9-9/lib/psiconv/generate_image.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 175 Revision 231
1/* 1/*
2
3 generate_image.c - Part of psiconv, a PSION 5 file formats converter 2 generate_image.c - Part of psiconv, a PSION 5 file formats converter
4 Copyright (c) 1999, 2000 Frodo Looijaard <frodol@dds.nl> 3 Copyright (c) 1999-2004 Frodo Looijaard <frodol@dds.nl>
5 4
6 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version. 8 (at your option) any later version.
22#include "compat.h" 21#include "compat.h"
23 22
24#include "generate_routines.h" 23#include "generate_routines.h"
25#include "error.h" 24#include "error.h"
26#include "list.h" 25#include "list.h"
26#include "image.h"
27 27
28#ifdef DMALLOC 28#ifdef DMALLOC
29#include <dmalloc.h> 29#include <dmalloc.h>
30#endif 30#endif
31 31
32typedef psiconv_list psiconv_pixel_bytes; /* psiconv_u8 */
33
34typedef psiconv_list psiconv_pixel_ints; /* of psiconv_u32 */
35
36typedef struct psiconv_pixel_float_s
37{
38 psiconv_u32 length;
39 float *red;
40 float *green;
41 float *blue;
42} psiconv_pixel_floats_t;
43 32
44static int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels, 33static int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,
45 int xsize,int ysize, 34 int xsize,int ysize,
46 const psiconv_pixel_floats_t data, 35 const psiconv_pixel_floats_t data,
47 int colordepth, 36 int colordepth,int color,
37 int redbits,int greenbits,int bluebits,
48 const psiconv_pixel_floats_t palet); 38 const psiconv_pixel_floats_t palet);
49static int psiconv_pixel_data_to_bytes(const psiconv_config config, 39static int psiconv_pixel_data_to_bytes(const psiconv_config config,int lev,
50 psiconv_pixel_bytes *bytes, int xsize, 40 psiconv_pixel_bytes *bytes, int xsize,
51 int ysize, const psiconv_pixel_ints pixels, 41 int ysize, const psiconv_pixel_ints pixels,
52 int colordepth); 42 int colordepth);
53static int psiconv_encode_rle8(const psiconv_config config, 43static int psiconv_encode_rle8(const psiconv_config config,
44 const psiconv_pixel_bytes plain_bytes,
45 psiconv_pixel_bytes *encoded_bytes);
46static int psiconv_encode_rle12(const psiconv_config config,
54 const psiconv_pixel_bytes plain_bytes, 47 const psiconv_pixel_bytes plain_bytes,
55 psiconv_pixel_bytes *encoded_bytes); 48 psiconv_pixel_bytes *encoded_bytes);
56static int psiconv_encode_rle16(const psiconv_config config, 49static int psiconv_encode_rle16(const psiconv_config config,
57 const psiconv_pixel_bytes plain_bytes, 50 const psiconv_pixel_bytes plain_bytes,
58 psiconv_pixel_bytes *encoded_bytes); 51 psiconv_pixel_bytes *encoded_bytes);
59static int psiconv_encode_rle24(const psiconv_config config, 52static int psiconv_encode_rle24(const psiconv_config config,
60 const psiconv_pixel_bytes plain_bytes, 53 const psiconv_pixel_bytes plain_bytes,
61 psiconv_pixel_bytes *encoded_bytes); 54 psiconv_pixel_bytes *encoded_bytes);
62 55
63#define PALET_GREY_2_LEN 4
64float palet_grey_2_rgb[PALET_GREY_2_LEN] = {0.0/3, 1.0/3, 2.0/3, 3.0/3};
65#define PALET_GREY_4_LEN 16
66float palet_grey_4_rgb[PALET_GREY_4_LEN] =
67 { 0.0/15, 1.0/15, 2.0/15, 3.0/15,
68 4.0/15, 5.0/15, 6.0/15, 7.0/15,
69 8.0/15, 9.0/15, 10.0/15, 11.0/15,
70 12.0/15, 13.0/15, 14.0/15, 15.0/15};
71#define PALET_NONE_LEN 0
72
73psiconv_pixel_floats_t palet_grey_2 =
74 {
75 PALET_GREY_2_LEN,
76 (float *) palet_grey_2_rgb,
77 (float *) palet_grey_2_rgb,
78 (float *) palet_grey_2_rgb
79 };
80
81psiconv_pixel_floats_t palet_grey_4 =
82 {
83 PALET_GREY_4_LEN,
84 (float *) palet_grey_4_rgb,
85 (float *) palet_grey_4_rgb,
86 (float *) palet_grey_4_rgb
87 };
88
89psiconv_pixel_floats_t palet_none =
90 {
91 PALET_NONE_LEN,
92 NULL,
93 NULL,
94 NULL
95 };
96
97
98int psiconv_write_paint_data_section(const psiconv_config config, 56int psiconv_write_paint_data_section(const psiconv_config config,
99 psiconv_buffer buf, 57 psiconv_buffer buf, int lev,
100 const psiconv_paint_data_section value, 58 const psiconv_paint_data_section value,
101 int is_clipart) 59 int is_clipart)
102{ 60{
103 int res,colordepth,i; 61 int res,colordepth,i;
104 psiconv_pixel_ints ints; 62 psiconv_pixel_ints ints;
105 psiconv_pixel_floats_t floats,palet; 63 psiconv_pixel_floats_t floats,palet;
106 psiconv_list bytes,bytes_rle; 64 psiconv_list bytes,bytes_rle;
107 psiconv_u8 *byteptr,encoding; 65 psiconv_u8 *byteptr,encoding;
108 66
67 psiconv_progress(config,lev,0,"Writing paint data section");
68
69 /* First, we check whether we can cope with the current configuration.
70 If not, we stop at once */
71 if ((config->colordepth != 2) && (config->colordepth != 4) &&
72 (config->colordepth != 8) && (config->colordepth != 12) &&
73 (config->colordepth != 16) && (config->colordepth != 24)) {
74 psiconv_error(config,lev,0,
75 "Unsupported color depth (%d); try 2, 4, 8, 16 or 24",
76 config->colordepth);
77 res = -PSICONV_E_GENERATE;
78 goto ERROR1;
79 }
80
81 if ((config->color) &&
82 (config->bluebits || config->redbits || config->greenbits) &&
83 (config->bluebits+config->redbits+config->greenbits!=config->colordepth)) {
84 psiconv_error(config,lev,0,
85 "Sum of red (%d), green (%d) and blue (%d) bits should be "
86 "equal to the color depth (%d)",
87 config->redbits,config->greenbits,config->bluebits,
88 config->colordepth);
89 res = -PSICONV_E_GENERATE;
90 goto ERROR1;
91 }
92
93 if (config->color &&
94 !(config->redbits || config->greenbits || config->bluebits) &&
95 (config->colordepth != 4) && (config->colordepth != 8)) {
96 psiconv_error(config,lev,0,
97 "Current color depth (%d) has no palet associated with it",
98 config->colordepth);
99 res = -PSICONV_E_GENERATE;
100 goto ERROR1;
101 }
102
103 if (config->color || (config->colordepth != 2))
104 psiconv_warn(config,lev,0,
105 "All image types except 2-bit greyscale are experimental!");
106
107
109 if (!value) { 108 if (!value) {
110 psiconv_warn(config,0,psiconv_buffer_length(buf),"Null paint data section"); 109 psiconv_error(config,lev,0,"Null paint data section");
111 res = -PSICONV_E_GENERATE; 110 res = -PSICONV_E_GENERATE;
112 goto ERROR1; 111 goto ERROR1;
113 } 112 }
114 113
115 floats.red = value->red; 114 floats.red = value->red;
116 floats.green = value->green; 115 floats.green = value->green;
117 floats.blue = value->blue; 116 floats.blue = value->blue;
118 floats.length = value->xsize * value->ysize; 117 floats.length = value->xsize * value->ysize;
119 118
119 palet = psiconv_palet_none;
120 if ((config->color) && (config->redbits == 0) && (config->greenbits == 0) &&
121 (config->bluebits == 0))
120 switch (config->colordepth) { 122 switch (config->colordepth) {
121 default: 123 case 4: palet = psiconv_palet_color_4; break;
122 case 2: palet = (config->color?palet_none:palet_grey_2); 124 case 8: palet = psiconv_palet_color_8; break;
123 break; 125 default: palet = psiconv_palet_none; break;
124 case 4: palet = (config->color?palet_none:palet_grey_4);
125 break;
126 } 126 }
127 127
128 if ((res = psiconv_collect_pixel_data(&ints,value->xsize, 128 if ((res = psiconv_collect_pixel_data(&ints,value->xsize,
129 value->ysize,floats, 129 value->ysize,floats,
130 config->colordepth,palet))) 130 config->colordepth,config->color,
131 config->redbits,config->greenbits,
132 config->bluebits,palet))) {
133 psiconv_error(config,lev,0,"Error collecting pixel data");
131 goto ERROR1; 134 goto ERROR1;
135 }
132 136
133 if ((res = psiconv_pixel_data_to_bytes(config,&bytes,value->xsize,value->ysize, 137 if ((res = psiconv_pixel_data_to_bytes(config,lev+1,&bytes,value->xsize,
134 ints,config->colordepth))) 138 value->ysize,ints,
139 config->colordepth))) {
140 psiconv_error(config,lev,0,"Error translating pixel data to bytes");
135 goto ERROR2; 141 goto ERROR2;
142 }
136 143
137 144
145 switch (config->colordepth) {
146 case 2:
147 case 4:
148 case 8:
138 encoding = 0x00; 149 encoding = 0x01;
139 if ((res = psiconv_encode_rle8(config,bytes,&bytes_rle))) 150 if ((res = psiconv_encode_rle8(config,bytes,&bytes_rle))) {
151 psiconv_error(config,lev,0,"Error encoding RLE8");
140 goto ERROR3; 152 goto ERROR3;
153 }
154 break;
155 case 12:
156 encoding = 0x02;
157 if ((res = psiconv_encode_rle12(config,bytes,&bytes_rle))) {
158 psiconv_error(config,lev,0,"Error encoding RLE12");
159 goto ERROR3;
160 }
161 break;
162 case 16:
163 encoding = 0x03;
164 if ((res = psiconv_encode_rle16(config,bytes,&bytes_rle))) {
165 psiconv_error(config,lev,0,"Error encoding RLE16");
166 goto ERROR3;
167 }
168 break;
169 case 24:
170 encoding = 0x04;
171 if ((res = psiconv_encode_rle24(config,bytes,&bytes_rle))) {
172 psiconv_error(config,lev,0,"Error encoding RLE24");
173 goto ERROR3;
174 }
175 break;
176 default:
177 encoding = 0x00;
178 }
179 if (encoding) {
141 if (psiconv_list_length(bytes_rle) < psiconv_list_length(bytes)) { 180 if (psiconv_list_length(bytes_rle) < psiconv_list_length(bytes)) {
142 encoding = 0x01;
143 psiconv_list_free(bytes); 181 psiconv_list_free(bytes);
144 bytes = bytes_rle; 182 bytes = bytes_rle;
145 } else { 183 } else {
146 bytes_rle = NULL; 184 psiconv_list_free(bytes_rle);
185 encoding = 0x00;
147 } 186 }
187 }
148 188
149 if ((res = psiconv_write_u32(config,buf, 189 if ((res = psiconv_write_u32(config,buf,lev+1,
150 0x28+psiconv_list_length(bytes)))) 190 0x28+psiconv_list_length(bytes))))
151 goto ERROR3; 191 goto ERROR3;
152 if ((res = psiconv_write_u32(config,buf,0x28))) 192 if ((res = psiconv_write_u32(config,buf,lev+1,0x28)))
153 goto ERROR3; 193 goto ERROR3;
154 if ((res = psiconv_write_u32(config,buf,value->xsize))) 194 if ((res = psiconv_write_u32(config,buf,lev+1,value->xsize)))
155 goto ERROR3; 195 goto ERROR3;
156 if ((res = psiconv_write_u32(config,buf,value->ysize))) 196 if ((res = psiconv_write_u32(config,buf,lev+1,value->ysize)))
157 goto ERROR3; 197 goto ERROR3;
158 if ((res = psiconv_write_length(config,buf,value->pic_xsize))) 198 if ((res = psiconv_write_length(config,buf,lev+1,value->pic_xsize)))
159 goto ERROR3; 199 goto ERROR3;
160 if ((res = psiconv_write_length(config,buf,value->pic_ysize))) 200 if ((res = psiconv_write_length(config,buf,lev+1,value->pic_ysize)))
161 goto ERROR3; 201 goto ERROR3;
162 colordepth = config->colordepth; 202 colordepth = config->colordepth;
163 if ((colordepth != 2) && colordepth != 4)
164 colordepth = 2;
165 if ((res = psiconv_write_u32(config,buf,colordepth))) 203 if ((res = psiconv_write_u32(config,buf,lev+1,colordepth)))
166 goto ERROR3; 204 goto ERROR3;
167 if ((res = psiconv_write_u32(config,buf,(config->color?1:0)))) 205 if ((res = psiconv_write_u32(config,buf,lev+1,(config->color?1:0))))
168 goto ERROR3; 206 goto ERROR3;
169 if ((res = psiconv_write_u32(config,buf,0))) 207 if ((res = psiconv_write_u32(config,buf,lev+1,0)))
170 goto ERROR3; 208 goto ERROR3;
171 if ((res = psiconv_write_u32(config,buf,encoding))) 209 if ((res = psiconv_write_u32(config,buf,lev+1,encoding)))
172 goto ERROR3; 210 goto ERROR3;
173 if (is_clipart) { 211 if (is_clipart) {
174 if ((res = psiconv_write_u32(config,buf,0xffffffff))) 212 if ((res = psiconv_write_u32(config,buf,lev+1,0xffffffff)))
175 goto ERROR3; 213 goto ERROR3;
176 if ((res = psiconv_write_u32(config,buf,0x00000044))) 214 if ((res = psiconv_write_u32(config,buf,lev+1,0x00000044)))
177 goto ERROR3; 215 goto ERROR3;
178 } 216 }
179 for (i = 0; i < psiconv_list_length(bytes); i++) { 217 for (i = 0; i < psiconv_list_length(bytes); i++) {
180 if (!(byteptr = psiconv_list_get(bytes,i))) 218 if (!(byteptr = psiconv_list_get(bytes,i)))
181 goto ERROR3; 219 goto ERROR3;
182 if ((res = psiconv_write_u8(config,buf,*byteptr))) 220 if ((res = psiconv_write_u8(config,buf,lev+1,*byteptr)))
183 goto ERROR3; 221 goto ERROR3;
184 } 222 }
185 223
186ERROR3: 224ERROR3:
187 psiconv_list_free(bytes); 225 psiconv_list_free(bytes);
188ERROR2: 226ERROR2:
189 psiconv_list_free(ints); 227 psiconv_list_free(ints);
190ERROR1: 228ERROR1:
229 if (res)
230 psiconv_error(config,lev,0,"Writing of paint data section failed");
231 else
232 psiconv_progress(config,lev,0,"End of paint data section");
191 return res; 233 return res;
192} 234}
193 235
194/* Translate the floating point RGB information into pixel values. 236/* Translate the floating point RGB information into pixel values.
195 The palet is optional; without it, we just use the 237 The palet is optional; without it, we just use the
196 colordepth. With a large palet this is not very fast, but it will do for 238 colordepth. With a large palet this is not very fast, but it will do for
197 now. For greyscale pictures, just use the palet. */ 239 now. For greyscale pictures, just use the palet. */
198int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,int xsize,int ysize, 240int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,int xsize,int ysize,
199 const psiconv_pixel_floats_t data, 241 const psiconv_pixel_floats_t data,
200 int colordepth, 242 int colordepth,int color,
243 int redbits,int bluebits,int greenbits,
201 const psiconv_pixel_floats_t palet) 244 const psiconv_pixel_floats_t palet)
202{ 245{
203 int res,x,y,i; 246 int res,x,y,i;
204 psiconv_u32 index,pixel; 247 psiconv_u32 index,pixel;
205 float p_red,p_green,p_blue,mult,dist,new_dist; 248 float p_red,p_green,p_blue,dist,new_dist;
206 249
207 if (!(*pixels = psiconv_list_new(sizeof(psiconv_u32)))) { 250 if (!(*pixels = psiconv_list_new(sizeof(psiconv_u32)))) {
208 res = -PSICONV_E_NOMEM; 251 res = -PSICONV_E_NOMEM;
209 goto ERROR1; 252 goto ERROR1;
210 } 253 }
211 254
212 mult = 1 << colordepth;
213 for (y = 0; y < ysize; y++) { 255 for (y = 0; y < ysize; y++) {
214 for (x = 0; x < xsize; x++) { 256 for (x = 0; x < xsize; x++) {
215 index = y*xsize+x; 257 index = y*xsize+x;
216 p_red = data.red[index]; 258 p_red = data.red[index];
217 p_green = data.green[index]; 259 p_green = data.green[index];
218 p_blue = data.blue[index]; 260 p_blue = data.blue[index];
219 if (!palet.length) { 261 if (!palet.length) {
220 pixel = (((psiconv_u32) (p_red*mult+0.5)) << (2*colordepth)) + 262 if (color)
221 (((psiconv_u32) (p_green*mult+0.5)) << colordepth) + 263 pixel = (((psiconv_u32) (p_red * (1 << redbits) + 0.5))
264 << (greenbits+bluebits)) +
265 (((psiconv_u32) (p_green * (1 << greenbits) + 0.5))
266 << bluebits) +
222 ((psiconv_u32) (p_blue*mult+0.5)); 267 ((psiconv_u32) (p_blue * (1 << bluebits) + 0.5));
268 else
269 pixel = (p_red + p_green + p_blue)/3.0 * (1 << colordepth);
223 } else { 270 } else {
224 dist = 4; /* Max distance is 3, so this is safe */ 271 dist = 4; /* Max distance is 3, so this is safe */
225 pixel = -1; 272 pixel = -1;
226 for (i = 0; i < palet.length; i++) { 273 for (i = 0; i < palet.length; i++) {
227 new_dist = (p_red - palet.red[i]) * (p_red - palet.red[i]) + 274 new_dist = (p_red - palet.red[i]) * (p_red - palet.red[i]) +
243 psiconv_list_free(*pixels); 290 psiconv_list_free(*pixels);
244ERROR1: 291ERROR1:
245 return res; 292 return res;
246} 293}
247 294
248int psiconv_pixel_data_to_bytes(const psiconv_config config, 295int psiconv_pixel_data_to_bytes(const psiconv_config config,int lev,
249 psiconv_pixel_bytes *bytes, int xsize, 296 psiconv_pixel_bytes *bytes, int xsize,
250 int ysize, const psiconv_pixel_ints pixels, 297 int ysize, const psiconv_pixel_ints pixels,
251 int colordepth) 298 int colordepth)
252{ 299{
253 int res; 300 int res;
258 psiconv_u32 *pixelptr; 305 psiconv_u32 *pixelptr;
259 int inputbitsleft,outputbitnr,bitsfit,outputbytenr; 306 int inputbitsleft,outputbitnr,bitsfit,outputbytenr;
260 307
261 308
262 if (!bytes) { 309 if (!bytes) {
263 psiconv_warn(config,0,0,"NULL pixel data"); 310 psiconv_error(config,lev,0,"NULL pixel data");
264 res = -PSICONV_E_GENERATE; 311 res = -PSICONV_E_GENERATE;
265 goto ERROR1; 312 goto ERROR1;
266 } 313 }
267 if (!pixels) { 314 if (!pixels) {
268 psiconv_warn(config,0,0,"NULL pixel data"); 315 psiconv_error(config,lev,0,"NULL pixel data");
269 res = -PSICONV_E_GENERATE; 316 res = -PSICONV_E_GENERATE;
270 goto ERROR1; 317 goto ERROR1;
271 } 318 }
272 if (psiconv_list_length(pixels) != xsize * ysize) { 319 if (psiconv_list_length(pixels) != xsize * ysize) {
273 psiconv_warn(config,0,0,"Pixel number is not correct"); 320 psiconv_error(config,lev,0,"Pixel number is not correct");
274 res = -PSICONV_E_GENERATE; 321 res = -PSICONV_E_GENERATE;
275 goto ERROR1; 322 goto ERROR1;
276 } 323 }
277 324
278 if (!(*bytes = psiconv_list_new(sizeof(psiconv_u8)))) { 325 if (!(*bytes = psiconv_list_new(sizeof(psiconv_u8)))) {
285 outputbyte = 0; 332 outputbyte = 0;
286 for (y = 0; y < ysize; y++) { 333 for (y = 0; y < ysize; y++) {
287 outputbytenr = 0; 334 outputbytenr = 0;
288 for (x = 0; x < xsize; x++) { 335 for (x = 0; x < xsize; x++) {
289 if (!(pixelptr = psiconv_list_get(pixels,y*xsize+x))) { 336 if (!(pixelptr = psiconv_list_get(pixels,y*xsize+x))) {
290 psiconv_warn(config,0,0,"Massive internal corruption"); 337 psiconv_error(config,lev,0,"Massive internal corruption");
291 res = -PSICONV_E_NOMEM; 338 res = -PSICONV_E_NOMEM;
292 goto ERROR2; 339 goto ERROR2;
293 } 340 }
294 inputbitsleft = colordepth; 341 inputbitsleft = colordepth;
295 inputdata = *pixelptr; 342 inputdata = *pixelptr;
330 psiconv_list_free(*bytes); 377 psiconv_list_free(*bytes);
331ERROR1: 378ERROR1:
332 return res; 379 return res;
333} 380}
334 381
382/* RLE8 encoding:
383 Marker bytes followed by one or more data bytes.
384 Marker value 0x00-0x7f: repeat the next data byte (marker+1) times
385 Marker value 0xff-0x80: (0x100-marker) data bytes follow */
335int psiconv_encode_rle8(const psiconv_config config, 386int psiconv_encode_rle8(const psiconv_config config,
336 const psiconv_pixel_bytes plain_bytes, 387 const psiconv_pixel_bytes plain_bytes,
337 psiconv_pixel_bytes *encoded_bytes) 388 psiconv_pixel_bytes *encoded_bytes)
338{ 389{
339 int res,i,j,len; 390 int res,i,j,len;
362 goto ERROR2; 413 goto ERROR2;
363 if ((res = psiconv_list_add(*encoded_bytes,next))) 414 if ((res = psiconv_list_add(*encoded_bytes,next)))
364 goto ERROR2; 415 goto ERROR2;
365 i +=2; 416 i +=2;
366 } else if (*next == *entry) { 417 } else if (*next == *entry) {
367 len = 0; 418 len = 1;
368 while ((*next == *entry) && 419 while ((*next == *entry) &&
369 (i+len + 1 < psiconv_list_length(plain_bytes)) && 420 (i+len + 2 < psiconv_list_length(plain_bytes)) &&
370 len < 0x80) { 421 len < 0x80) {
371 len ++; 422 len ++;
372 if (!(next = psiconv_list_get(plain_bytes,i+len))) { 423 if (!(next = psiconv_list_get(plain_bytes,i+len))) {
373 res = -PSICONV_E_NOMEM; 424 res = -PSICONV_E_NOMEM;
374 goto ERROR2; 425 goto ERROR2;
413 psiconv_list_free(*encoded_bytes); 464 psiconv_list_free(*encoded_bytes);
414ERROR1: 465ERROR1:
415 return res; 466 return res;
416} 467}
417 468
469/* RLE12 encoding:
470 Word based. The 12 least significant bits contain the pixel colors.
471 the 4 most signigicant bits are the number of repetitions minus 1 */
472int psiconv_encode_rle12(const psiconv_config config,
473 const psiconv_pixel_bytes plain_bytes,
474 psiconv_pixel_bytes *encoded_bytes)
475{
476 typedef psiconv_list psiconv_word_data; /* of psiconv_u16 */
477 psiconv_word_data data;
478 int res,i,len,location;
479 psiconv_u16 *word_entry,*word_next;
480 psiconv_u16 word_data;
481 psiconv_u8 byte_temp;
482 psiconv_u8 *byte_entry;
483
484
485 /* First extract the 12-bit values to encode */
486 if (!(data = psiconv_list_new(sizeof(psiconv_u16)))) {
487 res = -PSICONV_E_NOMEM;
488 goto ERROR1;
489 }
490
491 for (i = 0; i < psiconv_list_length(plain_bytes); i++) {
492 if (!(byte_entry = psiconv_list_get(plain_bytes,i))) {
493 res = -PSICONV_E_NOMEM;
494 goto ERROR2;
495 }
496 location = 0;
497 if (location == 0) {
498 word_data = *byte_entry;
499 location ++;
500 } else if (location == 1) {
501 word_data = (word_data << 4) + (*byte_entry & 0x0f);
502 if ((res = psiconv_list_add(data,&word_data)))
503 goto ERROR2;
504 word_data = *byte_entry >> 4;
505 location ++;
506 } else {
507 word_data = (word_data << 8) + *byte_entry;
508 if ((res = psiconv_list_add(data,&word_data)))
509 goto ERROR2;
510 location = 0;
511 }
512 }
513
514 if (!(*encoded_bytes = psiconv_list_new(sizeof(psiconv_u8)))) {
515 res = -PSICONV_E_NOMEM;
516 goto ERROR2;
517 }
518
519 for (i = 0; i < psiconv_list_length(data);) {
520 if (!(word_entry = psiconv_list_get(data,i))) {
521 res = -PSICONV_E_NOMEM;
522 goto ERROR3;
523 }
524
525 if (!(word_next = psiconv_list_get(data,i+1))) {
526 res = -PSICONV_E_NOMEM;
527 goto ERROR3;
528 }
529
530 if (i == psiconv_list_length(data) - 2) {
531 byte_temp = *word_entry && 0xff;
532 if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
533 goto ERROR3;
534 byte_temp = *word_entry >> 8;
535 if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
536 goto ERROR3;
537 byte_temp = *word_next && 0xff;
538 if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
539 goto ERROR3;
540 byte_temp = *word_next >> 8;
541 if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
542 goto ERROR3;
543 i += 2;
544 }
545
546 len = 0;
547 while ((*word_entry == *word_next) && (len < 16) &&
548 (i+len+1 < psiconv_list_length(data))) {
549 len ++;
550 if (!(word_next = psiconv_list_get(data,i+len))) {
551 res = -PSICONV_E_NOMEM;
552 goto ERROR3;
553 }
554 }
555
556 byte_temp = *word_entry && 0xff;
557 if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
558 goto ERROR3;
559 byte_temp = (*word_entry >> 8) + ((len - 1) << 4);
560 if ((res = psiconv_list_add(*encoded_bytes,&byte_temp)))
561 goto ERROR3;
562 i += len;
563 }
564 return 0;
565
566ERROR3:
567 psiconv_list_free(*encoded_bytes);
568ERROR2:
569 psiconv_list_free(data);
570ERROR1:
571 return res;
572}
573
574/* RLE16 encoding:
575 Marker bytes followed by one or more data words.
576 Marker value 0x00-0x7f: repeat the next data word (marker+1) times
577 Marker value 0xff-0x80: (0x100-marker) data words follow */
418int psiconv_encode_rle16(const psiconv_config config, 578int psiconv_encode_rle16(const psiconv_config config,
419 const psiconv_pixel_bytes plain_bytes, 579 const psiconv_pixel_bytes plain_bytes,
420 psiconv_pixel_bytes *encoded_bytes) 580 psiconv_pixel_bytes *encoded_bytes)
421{ 581{
422 int res,i,j,len; 582 int res,i,j,len;
525 psiconv_list_free(*encoded_bytes); 685 psiconv_list_free(*encoded_bytes);
526ERROR1: 686ERROR1:
527 return res; 687 return res;
528} 688}
529 689
690/* RLE24 encoding:
691 Marker bytes followed by one or more data byte-triplets.
692 Marker value 0x00-0x7f: repeat the next data byte-triplets (marker+1) times
693 Marker value 0xff-0x80: (0x100-marker) data byte-triplets follow */
530int psiconv_encode_rle24(const psiconv_config config, 694int psiconv_encode_rle24(const psiconv_config config,
531 const psiconv_pixel_bytes plain_bytes, 695 const psiconv_pixel_bytes plain_bytes,
532 psiconv_pixel_bytes *encoded_bytes) 696 psiconv_pixel_bytes *encoded_bytes)
533{ 697{
534 int res,i,j,len; 698 int res,i,j,len;
671 return res; 835 return res;
672} 836}
673 837
674 838
675int psiconv_write_sketch_section(const psiconv_config config, 839int psiconv_write_sketch_section(const psiconv_config config,
676 psiconv_buffer buf, 840 psiconv_buffer buf, int lev,
677 const psiconv_sketch_section value) 841 const psiconv_sketch_section value)
678{ 842{
679 int res; 843 int res;
680 844
845 psiconv_progress(config,lev,0,"Writing sketch section");
681 if (!value) { 846 if (!value) {
682 psiconv_warn(config,0,0,"NULL sketch section"); 847 psiconv_error(config,lev,0,"NULL sketch section");
683 res = -PSICONV_E_GENERATE; 848 res = -PSICONV_E_GENERATE;
684 goto ERROR1; 849 goto ERROR1;
685 } 850 }
686 851
687 if ((res = psiconv_write_u16(config,buf,value->displayed_xsize))) 852 if ((res = psiconv_write_u16(config,buf,lev+1,value->displayed_xsize)))
688 goto ERROR1; 853 goto ERROR1;
689 if ((res = psiconv_write_u16(config,buf,value->displayed_ysize))) 854 if ((res = psiconv_write_u16(config,buf,lev+1,value->displayed_ysize)))
690 goto ERROR1; 855 goto ERROR1;
691 if ((res = psiconv_write_u16(config,buf,value->picture_data_x_offset))) 856 if ((res = psiconv_write_u16(config,buf,lev+1,value->picture_data_x_offset)))
692 goto ERROR1; 857 goto ERROR1;
693 if ((res = psiconv_write_u16(config,buf,value->picture_data_y_offset))) 858 if ((res = psiconv_write_u16(config,buf,lev+1,value->picture_data_y_offset)))
694 goto ERROR1; 859 goto ERROR1;
695 if ((res = psiconv_write_u16(config,buf,value->displayed_size_x_offset))) 860 if ((res = psiconv_write_u16(config,buf,lev+1,value->displayed_size_x_offset)))
696 goto ERROR1; 861 goto ERROR1;
697 if ((res = psiconv_write_u16(config,buf,value->displayed_size_y_offset))) 862 if ((res = psiconv_write_u16(config,buf,lev+1,value->displayed_size_y_offset)))
698 goto ERROR1; 863 goto ERROR1;
699 if ((res = psiconv_write_u16(config,buf,value->form_xsize))) 864 if ((res = psiconv_write_u16(config,buf,lev+1,value->form_xsize)))
700 goto ERROR1; 865 goto ERROR1;
701 if ((res = psiconv_write_u16(config,buf,value->form_ysize))) 866 if ((res = psiconv_write_u16(config,buf,lev+1,value->form_ysize)))
702 goto ERROR1; 867 goto ERROR1;
703 if ((res = psiconv_write_u16(config,buf,0x0000))) 868 if ((res = psiconv_write_u16(config,buf,lev+1,0x0000)))
704 goto ERROR1; 869 goto ERROR1;
705 if ((res = psiconv_write_paint_data_section(config,buf,value->picture,0))) 870 if ((res = psiconv_write_paint_data_section(config,buf,lev+1,value->picture,0)))
706 goto ERROR1; 871 goto ERROR1;
707 if ((res = psiconv_write_u16(config,buf,value->magnification_x * 0x03e8))) 872 if ((res = psiconv_write_u16(config,buf,lev+1,value->magnification_x * 0x03e8)))
708 goto ERROR1; 873 goto ERROR1;
709 if ((res = psiconv_write_u16(config,buf,value->magnification_y * 0x03e8))) 874 if ((res = psiconv_write_u16(config,buf,lev+1,value->magnification_y * 0x03e8)))
710 goto ERROR1; 875 goto ERROR1;
711 if ((res = psiconv_write_u32(config,buf,value->cut_left * 0x0c * 876 if ((res = psiconv_write_u32(config,buf,lev+1,value->cut_left * 0x0c *
712 value->displayed_xsize))) 877 value->displayed_xsize)))
713 goto ERROR1; 878 goto ERROR1;
714 if ((res = psiconv_write_u32(config,buf,value->cut_right * 0x0c * 879 if ((res = psiconv_write_u32(config,buf,lev+1,value->cut_right * 0x0c *
715 value->displayed_xsize))) 880 value->displayed_xsize)))
716 goto ERROR1; 881 goto ERROR1;
717 if ((res = psiconv_write_u32(config,buf,value->cut_top * 0x0c * 882 if ((res = psiconv_write_u32(config,buf,lev+1,value->cut_top * 0x0c *
718 value->displayed_ysize))) 883 value->displayed_ysize)))
719 goto ERROR1; 884 goto ERROR1;
720 if ((res = psiconv_write_u32(config,buf,value->cut_bottom * 0x0c * 885 if ((res = psiconv_write_u32(config,buf,lev+1,value->cut_bottom * 0x0c *
721 value->displayed_ysize))) 886 value->displayed_ysize)))
722 goto ERROR1; 887 goto ERROR1;
723 888
724ERROR1: 889ERROR1:
890 if (res)
891 psiconv_error(config,lev,0,"Writing of sketch section failed");
892 else
893 psiconv_progress(config,lev,0,"End of sketch section");
725 return res; 894 return res;
726} 895}
727 896
728int psiconv_write_clipart_section(const psiconv_config config, 897int psiconv_write_clipart_section(const psiconv_config config,
729 psiconv_buffer buf, 898 psiconv_buffer buf, int lev,
730 const psiconv_clipart_section value) 899 const psiconv_clipart_section value)
731{ 900{
732 int res; 901 int res;
733 902
734 903 psiconv_progress(config,lev,0,"Writing clipart section");
735 if (!value) { 904 if (!value) {
736 psiconv_warn(config,0,psiconv_buffer_length(buf), 905 psiconv_error(config,lev,0, "NULL Clipart Section");
737 "NULL Clipart Section");
738 res = -PSICONV_E_GENERATE; 906 res = -PSICONV_E_GENERATE;
739 goto ERROR; 907 goto ERROR;
740 } 908 }
741 if ((res = psiconv_write_u32(config,buf,PSICONV_ID_CLIPART_ITEM))) 909 if ((res = psiconv_write_u32(config,buf,lev+1,PSICONV_ID_CLIPART_ITEM)))
742 goto ERROR; 910 goto ERROR;
743 if ((res = psiconv_write_u32(config,buf,0x00000002))) 911 if ((res = psiconv_write_u32(config,buf,lev+1,0x00000002)))
744 goto ERROR; 912 goto ERROR;
745 if ((res = psiconv_write_u32(config,buf,0x00000000))) 913 if ((res = psiconv_write_u32(config,buf,lev+1,0x00000000)))
746 goto ERROR; 914 goto ERROR;
747 if ((res = psiconv_write_u32(config,buf,0x00000000))) 915 if ((res = psiconv_write_u32(config,buf,lev+1,0x00000000)))
748 goto ERROR; 916 goto ERROR;
749 if ((res = psiconv_write_u32(config,buf,0x0000000C))) 917 if ((res = psiconv_write_u32(config,buf,lev+1,0x0000000C)))
750 goto ERROR; 918 goto ERROR;
751 if ((res = psiconv_write_paint_data_section(config,buf,value->picture,1))) 919 if ((res = psiconv_write_paint_data_section(config,buf,lev+1,value->picture,1)))
752 goto ERROR; 920 goto ERROR;
753 921
754ERROR: 922ERROR:
923 if (res)
924 psiconv_error(config,lev,0,"Writing of clipart section failed");
925 else
926 psiconv_progress(config,lev,0,"End of clipart section");
755 return res; 927 return res;
756} 928}
757 929
758int psiconv_write_jumptable_section(const psiconv_config config, 930int psiconv_write_jumptable_section(const psiconv_config config,
759 psiconv_buffer buf, 931 psiconv_buffer buf, int lev,
760 const psiconv_jumptable_section value) 932 const psiconv_jumptable_section value)
761{ 933{
762 int res,i; 934 int res,i;
763 psiconv_u32 *offset_ptr; 935 psiconv_u32 *offset_ptr;
764 936
937 psiconv_progress(config,lev,0,"Writing jumptable section");
765 938
766 if (!value) { 939 if (!value) {
767 psiconv_warn(config,0,psiconv_buffer_length(buf), 940 psiconv_error(config,lev,0,"NULL Jumptable Section");
768 "NULL Jumptable Section");
769 res = -PSICONV_E_GENERATE; 941 res = -PSICONV_E_GENERATE;
770 goto ERROR; 942 goto ERROR;
771 } 943 }
772 if ((res = psiconv_write_u32(config,buf,psiconv_list_length(value)))) 944 if ((res = psiconv_write_u32(config,buf,lev+1,psiconv_list_length(value))))
773 goto ERROR; 945 goto ERROR;
774 for (i = 0; i < psiconv_list_length(value); i++) { 946 for (i = 0; i < psiconv_list_length(value); i++) {
775 if (!(offset_ptr = psiconv_list_get(value,i))) { 947 if (!(offset_ptr = psiconv_list_get(value,i))) {
776 psiconv_warn(config,0,psiconv_buffer_length(buf), 948 psiconv_error(config,lev,0,"Massive memory corruption");
777 "Massive memory corruption");
778 res = -PSICONV_E_NOMEM; 949 res = -PSICONV_E_NOMEM;
779 goto ERROR; 950 goto ERROR;
780 } 951 }
781 if ((res = psiconv_write_offset(config,buf,*offset_ptr))) 952 if ((res = psiconv_write_offset(config,buf,lev+1,*offset_ptr)))
782 goto ERROR; 953 goto ERROR;
783 } 954 }
784 955
785ERROR: 956ERROR:
957 if (res)
958 psiconv_error(config,lev,0,"Writing of jumptable section failed");
959 else
960 psiconv_progress(config,lev,0,"End of jumptable section");
786 return res; 961 return res;
787} 962}
788 963

Legend:
Removed from v.175  
changed lines
  Added in v.231

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