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

Diff of /psiconv/trunk/lib/psiconv/generate_image.c

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

Revision 168 Revision 175
1/* 1/*
2
2 generate_image.c - Part of psiconv, a PSION 5 file formats converter 3 generate_image.c - Part of psiconv, a PSION 5 file formats converter
3 Copyright (c) 1999, 2000 Frodo Looijaard <frodol@dds.nl> 4 Copyright (c) 1999, 2000 Frodo Looijaard <frodol@dds.nl>
4 5
5 This program is free software; you can redistribute it and/or modify 6 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 it under the terms of the GNU General Public License as published by
20#include "config.h" 21#include "config.h"
21#include "compat.h" 22#include "compat.h"
22 23
23#include "generate_routines.h" 24#include "generate_routines.h"
24#include "error.h" 25#include "error.h"
26#include "list.h"
25 27
26#ifdef DMALLOC 28#ifdef DMALLOC
27#include <dmalloc.h> 29#include <dmalloc.h>
28#endif 30#endif
29 31
31 33
32typedef psiconv_list psiconv_pixel_ints; /* of psiconv_u32 */ 34typedef psiconv_list psiconv_pixel_ints; /* of psiconv_u32 */
33 35
34typedef struct psiconv_pixel_float_s 36typedef struct psiconv_pixel_float_s
35{ 37{
38 psiconv_u32 length;
36 float *red; 39 float *red;
37 float *green; 40 float *green;
38 float *blue; 41 float *blue;
39} psiconv_pixel_floats_t; 42} psiconv_pixel_floats_t;
40 43
41static int psiconv_collect_pixel_data(const psiconv_config config, 44static int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,
42 psiconv_pixel_ints *pixels,int xsize,
43 int ysize, 45 int xsize,int ysize,
44 const psiconv_pixel_floats_t data, 46 const psiconv_pixel_floats_t data,
45 int colordepth, int palet_len, 47 int colordepth,
46 const psiconv_pixel_floats_t palet); 48 const psiconv_pixel_floats_t palet);
47
48static int psiconv_pixel_data_to_bytes(const psiconv_config config, psiconv_pixel_bytes *bytes, int xsize, 49static int psiconv_pixel_data_to_bytes(const psiconv_config config,
50 psiconv_pixel_bytes *bytes, int xsize,
49 int ysize, const psiconv_pixel_ints pixels, 51 int ysize, const psiconv_pixel_ints pixels,
50 int colordepth); 52 int colordepth);
53static int psiconv_encode_rle8(const psiconv_config config,
54 const psiconv_pixel_bytes plain_bytes,
55 psiconv_pixel_bytes *encoded_bytes);
56static int psiconv_encode_rle16(const psiconv_config config,
57 const psiconv_pixel_bytes plain_bytes,
58 psiconv_pixel_bytes *encoded_bytes);
59static int psiconv_encode_rle24(const psiconv_config config,
60 const psiconv_pixel_bytes plain_bytes,
61 psiconv_pixel_bytes *encoded_bytes);
51 62
63#define PALET_GREY_2_LEN 4
52float palet_grey_2_rgb[4] = {0.0/3, 1.0/3, 2.0/3, 3.0/3}; 64float palet_grey_2_rgb[PALET_GREY_2_LEN] = {0.0/3, 1.0/3, 2.0/3, 3.0/3};
53float palet_grey_4_rgb[16] = { 0.0/15, 1.0/15, 2.0/15, 3.0/15, 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,
54 4.0/15, 5.0/15, 6.0/15, 7.0/15, 68 4.0/15, 5.0/15, 6.0/15, 7.0/15,
55 8.0/15, 9.0/15, 10.0/15, 11.0/15, 69 8.0/15, 9.0/15, 10.0/15, 11.0/15,
56 12.0/15, 13.0/15, 14.0/15, 15.0/15}; 70 12.0/15, 13.0/15, 14.0/15, 15.0/15};
71#define PALET_NONE_LEN 0
57 72
58psiconv_pixel_floats_t palet_grey_2 = 73psiconv_pixel_floats_t palet_grey_2 =
59 { 74 {
75 PALET_GREY_2_LEN,
60 (float *) palet_grey_2_rgb, 76 (float *) palet_grey_2_rgb,
61 (float *) palet_grey_2_rgb, 77 (float *) palet_grey_2_rgb,
62 (float *) palet_grey_2_rgb 78 (float *) palet_grey_2_rgb
63 }; 79 };
64 80
65psiconv_pixel_floats_t palet_grey_4 = 81psiconv_pixel_floats_t palet_grey_4 =
66 { 82 {
83 PALET_GREY_4_LEN,
67 (float *) palet_grey_4_rgb, 84 (float *) palet_grey_4_rgb,
68 (float *) palet_grey_4_rgb, 85 (float *) palet_grey_4_rgb,
69 (float *) palet_grey_4_rgb 86 (float *) palet_grey_4_rgb
70 }; 87 };
71 88
89psiconv_pixel_floats_t palet_none =
90 {
91 PALET_NONE_LEN,
92 NULL,
93 NULL,
94 NULL
95 };
72 96
73/* For now, we only write 2-bit non-RLE-encoded stuff */ 97
74int psiconv_write_paint_data_section(const psiconv_config config, 98int psiconv_write_paint_data_section(const psiconv_config config,
75 psiconv_buffer buf, 99 psiconv_buffer buf,
76 const psiconv_paint_data_section value) 100 const psiconv_paint_data_section value,
101 int is_clipart)
77{ 102{
78 int res; 103 int res,colordepth,i;
79 psiconv_buffer pix_buf; 104 psiconv_pixel_ints ints;
105 psiconv_pixel_floats_t floats,palet;
106 psiconv_list bytes,bytes_rle;
107 psiconv_u8 *byteptr,encoding;
80 108
81 if (!value) { 109 if (!value) {
82 psiconv_warn(config,0,psiconv_buffer_length(buf),"Null paint data section"); 110 psiconv_warn(config,0,psiconv_buffer_length(buf),"Null paint data section");
83 res = -PSICONV_E_GENERATE; 111 res = -PSICONV_E_GENERATE;
84 goto ERROR1; 112 goto ERROR1;
85 } 113 }
86 114
87 if (!(pix_buf = psiconv_buffer_new())) { 115 floats.red = value->red;
88 res = -PSICONV_E_NOMEM; 116 floats.green = value->green;
117 floats.blue = value->blue;
118 floats.length = value->xsize * value->ysize;
119
120 switch (config->colordepth) {
121 default:
122 case 2: palet = (config->color?palet_none:palet_grey_2);
123 break;
124 case 4: palet = (config->color?palet_none:palet_grey_4);
125 break;
126 }
127
128 if ((res = psiconv_collect_pixel_data(&ints,value->xsize,
129 value->ysize,floats,
130 config->colordepth,palet)))
131 goto ERROR1;
132
133 if ((res = psiconv_pixel_data_to_bytes(config,&bytes,value->xsize,value->ysize,
134 ints,config->colordepth)))
89 goto ERROR1; 135 goto ERROR2;
90 }
91 136
92 return 0;
93 137
138 encoding = 0x00;
139 if ((res = psiconv_encode_rle8(config,bytes,&bytes_rle)))
140 goto ERROR3;
141 if (psiconv_list_length(bytes_rle) < psiconv_list_length(bytes)) {
142 encoding = 0x01;
143 psiconv_list_free(bytes);
144 bytes = bytes_rle;
145 } else {
146 bytes_rle = NULL;
147 }
148
149 if ((res = psiconv_write_u32(config,buf,
150 0x28+psiconv_list_length(bytes))))
151 goto ERROR3;
152 if ((res = psiconv_write_u32(config,buf,0x28)))
153 goto ERROR3;
154 if ((res = psiconv_write_u32(config,buf,value->xsize)))
155 goto ERROR3;
156 if ((res = psiconv_write_u32(config,buf,value->ysize)))
157 goto ERROR3;
158 if ((res = psiconv_write_length(config,buf,value->pic_xsize)))
159 goto ERROR3;
160 if ((res = psiconv_write_length(config,buf,value->pic_ysize)))
161 goto ERROR3;
162 colordepth = config->colordepth;
163 if ((colordepth != 2) && colordepth != 4)
164 colordepth = 2;
165 if ((res = psiconv_write_u32(config,buf,colordepth)))
166 goto ERROR3;
167 if ((res = psiconv_write_u32(config,buf,(config->color?1:0))))
168 goto ERROR3;
169 if ((res = psiconv_write_u32(config,buf,0)))
170 goto ERROR3;
171 if ((res = psiconv_write_u32(config,buf,encoding)))
172 goto ERROR3;
173 if (is_clipart) {
174 if ((res = psiconv_write_u32(config,buf,0xffffffff)))
175 goto ERROR3;
176 if ((res = psiconv_write_u32(config,buf,0x00000044)))
177 goto ERROR3;
178 }
179 for (i = 0; i < psiconv_list_length(bytes); i++) {
180 if (!(byteptr = psiconv_list_get(bytes,i)))
181 goto ERROR3;
182 if ((res = psiconv_write_u8(config,buf,*byteptr)))
183 goto ERROR3;
184 }
185
186ERROR3:
187 psiconv_list_free(bytes);
94ERROR2: 188ERROR2:
95 psiconv_buffer_free(pix_buf); 189 psiconv_list_free(ints);
96ERROR1: 190ERROR1:
97 return res; 191 return res;
98} 192}
99 193
100/* Translate the floating point RGB information into pixel values. 194/* Translate the floating point RGB information into pixel values.
101 The palet is optional; without it, we just use the 195 The palet is optional; without it, we just use the
102 colordepth. With a large palet this is not very fast, but it will do for 196 colordepth. With a large palet this is not very fast, but it will do for
103 now. For greyscale pictures, just use the palet. */ 197 now. For greyscale pictures, just use the palet. */
104int psiconv_collect_pixel_data(const psiconv_config config, 198int psiconv_collect_pixel_data(psiconv_pixel_ints *pixels,int xsize,int ysize,
105 psiconv_pixel_ints *pixels,int xsize,int ysize,
106 const psiconv_pixel_floats_t data, 199 const psiconv_pixel_floats_t data,
107 int colordepth, int palet_len, 200 int colordepth,
108 const psiconv_pixel_floats_t palet) 201 const psiconv_pixel_floats_t palet)
109{ 202{
110 int res,x,y,i; 203 int res,x,y,i;
111 psiconv_u32 index,mask,pixel; 204 psiconv_u32 index,pixel;
112 float p_red,p_green,p_blue,mult,dist,new_dist; 205 float p_red,p_green,p_blue,mult,dist,new_dist;
113 206
114 if (!(*pixels = psiconv_list_new(sizeof(psiconv_u32)))) { 207 if (!(*pixels = psiconv_list_new(sizeof(psiconv_u32)))) {
115 res = -PSICONV_E_NOMEM; 208 res = -PSICONV_E_NOMEM;
116 goto ERROR1; 209 goto ERROR1;
117 } 210 }
118 211
119 mult = 1 << colordepth; 212 mult = 1 << colordepth;
120 mask = mult -1;
121 for (y = 0; y < ysize; y++) { 213 for (y = 0; y < ysize; y++) {
122 for (x = 0; x < xsize; x++) { 214 for (x = 0; x < xsize; x++) {
123 index = y*ysize+x; 215 index = y*xsize+x;
124 p_red = data.red[index]; 216 p_red = data.red[index];
125 p_green = data.green[index]; 217 p_green = data.green[index];
126 p_blue = data.blue[index]; 218 p_blue = data.blue[index];
127 if (! palet_len) { 219 if (!palet.length) {
128 pixel = (((psiconv_u32) (p_red*mult) & mask) << (2*colordepth)) + 220 pixel = (((psiconv_u32) (p_red*mult+0.5)) << (2*colordepth)) +
129 (((psiconv_u32) (p_green*mult) & mask) << colordepth) + 221 (((psiconv_u32) (p_green*mult+0.5)) << colordepth) +
130 ((psiconv_u32) (p_blue*mult) & mask); 222 ((psiconv_u32) (p_blue*mult+0.5));
131 } else { 223 } else {
132 dist = 4; /* Max distance is 3, so this is safe */ 224 dist = 4; /* Max distance is 3, so this is safe */
133 pixel = -1; 225 pixel = -1;
134 for (i = 0; i < palet_len; i++) { 226 for (i = 0; i < palet.length; i++) {
135 new_dist = (p_red - palet.red[i]) * (p_red - palet.red[i]) + 227 new_dist = (p_red - palet.red[i]) * (p_red - palet.red[i]) +
136 (p_green - palet.green[i]) * (p_green - palet.green[i]) + 228 (p_green - palet.green[i]) * (p_green - palet.green[i]) +
137 (p_blue - palet.blue[i]) * (p_blue - palet.blue[i]); 229 (p_blue - palet.blue[i]) * (p_blue - palet.blue[i]);
138 if (new_dist < dist) { 230 if (new_dist < dist) {
139 pixel = i; 231 pixel = i;
151 psiconv_list_free(*pixels); 243 psiconv_list_free(*pixels);
152ERROR1: 244ERROR1:
153 return res; 245 return res;
154} 246}
155 247
156int psiconv_pixel_data_to_bytes(const psiconv_config config, psiconv_pixel_bytes *bytes, int xsize, 248int psiconv_pixel_data_to_bytes(const psiconv_config config,
249 psiconv_pixel_bytes *bytes, int xsize,
157 int ysize, const psiconv_pixel_ints pixels, 250 int ysize, const psiconv_pixel_ints pixels,
158 int colordepth) 251 int colordepth)
159{ 252{
160 int res; 253 int res;
161 int x,y; 254 int x,y;
162 255
163 psiconv_u32 inputdata; 256 psiconv_u32 inputdata;
164 psiconv_u8 outputbyte; 257 psiconv_u8 outputbyte;
165 psiconv_u32 *pixelptr; 258 psiconv_u32 *pixelptr;
166 int inputbitsleft,outputbitnr,bitsfit; 259 int inputbitsleft,outputbitnr,bitsfit,outputbytenr;
167 260
168 261
169 if (!bytes) { 262 if (!bytes) {
170 psiconv_warn(config,0,0,"NULL pixel data"); 263 psiconv_warn(config,0,0,"NULL pixel data");
171 res = -PSICONV_E_GENERATE; 264 res = -PSICONV_E_GENERATE;
189 282
190 283
191 outputbitnr = 0; 284 outputbitnr = 0;
192 outputbyte = 0; 285 outputbyte = 0;
193 for (y = 0; y < ysize; y++) { 286 for (y = 0; y < ysize; y++) {
287 outputbytenr = 0;
194 for (x = 0; x < xsize; x++) { 288 for (x = 0; x < xsize; x++) {
195 if (!(pixelptr = psiconv_list_get(pixels,y*xsize+x))) { 289 if (!(pixelptr = psiconv_list_get(pixels,y*xsize+x))) {
196 psiconv_warn(config,0,0,"Massive internal corruption"); 290 psiconv_warn(config,0,0,"Massive internal corruption");
197 res = -PSICONV_E_NOMEM; 291 res = -PSICONV_E_NOMEM;
198 goto ERROR2; 292 goto ERROR2;
208 if (outputbitnr == 8) { 302 if (outputbitnr == 8) {
209 if ((res = psiconv_list_add(*bytes,&outputbyte))) 303 if ((res = psiconv_list_add(*bytes,&outputbyte)))
210 goto ERROR2; 304 goto ERROR2;
211 outputbitnr = 0; 305 outputbitnr = 0;
212 outputbyte = 0; 306 outputbyte = 0;
307 outputbytenr ++;
213 } 308 }
214 } 309 }
215 } 310 }
216 /* Always end lines on a byte border */ 311 /* Always end lines on a long border */
217 if (outputbitnr != 0) { 312 if (outputbitnr != 0) {
218 if ((res = psiconv_list_add(*bytes,&outputbyte))) 313 if ((res = psiconv_list_add(*bytes,&outputbyte)))
219 goto ERROR2; 314 goto ERROR2;
220 outputbitnr = 0; 315 outputbitnr = 0;
221 outputbyte = 0; 316 outputbyte = 0;
317 outputbytenr ++;
318 }
319
320 while (outputbytenr % 0x04) {
321 if ((res = psiconv_list_add(*bytes,&outputbyte)))
322 goto ERROR2;
323 outputbytenr ++;
222 } 324 }
223 } 325 }
224 326
225 return 0; 327 return 0;
226 328
227ERROR2: 329ERROR2:
228 psiconv_list_free(*bytes); 330 psiconv_list_free(*bytes);
229ERROR1: 331ERROR1:
230 return res; 332 return res;
231} 333}
334
335int psiconv_encode_rle8(const psiconv_config config,
336 const psiconv_pixel_bytes plain_bytes,
337 psiconv_pixel_bytes *encoded_bytes)
338{
339 int res,i,j,len;
340 psiconv_u8 *entry,*next;
341 psiconv_u8 temp;
342
343 if (!(*encoded_bytes = psiconv_list_new(sizeof(*entry)))) {
344 res = -PSICONV_E_NOMEM;
345 goto ERROR1;
346 }
347
348 for (i = 0; i < psiconv_list_length(plain_bytes);) {
349 if (!(entry = psiconv_list_get(plain_bytes,i))) {
350 res = -PSICONV_E_NOMEM;
351 goto ERROR2;
352 }
353 if (!(next = psiconv_list_get(plain_bytes,i+1))) {
354 res = -PSICONV_E_NOMEM;
355 goto ERROR2;
356 }
357 if (i == psiconv_list_length(plain_bytes) - 2) {
358 temp = 0xfe;
359 if ((res = psiconv_list_add(*encoded_bytes,&temp)))
360 goto ERROR2;
361 if ((res = psiconv_list_add(*encoded_bytes,entry)))
362 goto ERROR2;
363 if ((res = psiconv_list_add(*encoded_bytes,next)))
364 goto ERROR2;
365 i +=2;
366 } else if (*next == *entry) {
367 len = 0;
368 while ((*next == *entry) &&
369 (i+len + 1 < psiconv_list_length(plain_bytes)) &&
370 len < 0x80) {
371 len ++;
372 if (!(next = psiconv_list_get(plain_bytes,i+len))) {
373 res = -PSICONV_E_NOMEM;
374 goto ERROR2;
375 }
376 }
377 temp = len - 1;
378 if ((res = psiconv_list_add(*encoded_bytes,&temp)))
379 goto ERROR2;
380 if ((res = psiconv_list_add(*encoded_bytes,entry)))
381 goto ERROR2;
382 i += len;
383 } else {
384 len = 1;
385 while ((*next != *entry) &&
386 (i+len+1 < psiconv_list_length(plain_bytes)) &&
387 len < 0x80) {
388 len ++;
389 entry = next;
390 if (!(next = psiconv_list_get(plain_bytes,i+len))) {
391 res = -PSICONV_E_NOMEM;
392 goto ERROR2;
393 }
394 }
395 len --;
396 temp = 0x100 - len;
397 if ((res = psiconv_list_add(*encoded_bytes,&temp)))
398 goto ERROR2;
399 for (j = 0; j < len; j++) {
400 if (!(next = psiconv_list_get(plain_bytes,i+j))) {
401 res = -PSICONV_E_NOMEM;
402 goto ERROR2;
403 }
404 if ((res = psiconv_list_add(*encoded_bytes,next)))
405 goto ERROR2;
406 }
407 i += len;
408 }
409 }
410 return 0;
411
412ERROR2:
413 psiconv_list_free(*encoded_bytes);
414ERROR1:
415 return res;
416}
417
418int psiconv_encode_rle16(const psiconv_config config,
419 const psiconv_pixel_bytes plain_bytes,
420 psiconv_pixel_bytes *encoded_bytes)
421{
422 int res,i,j,len;
423 psiconv_u8 *entry1,*entry2,*next1,*next2;
424 psiconv_u8 temp;
425
426 if (!(*encoded_bytes = psiconv_list_new(sizeof(*entry1)))) {
427 res = -PSICONV_E_NOMEM;
428 goto ERROR1;
429 }
430
431 for (i = 0; i < psiconv_list_length(plain_bytes);) {
432 if (!(entry1 = psiconv_list_get(plain_bytes,i))) {
433 res = -PSICONV_E_NOMEM;
434 goto ERROR2;
435 }
436 if (!(entry2 = psiconv_list_get(plain_bytes,i+1))) {
437 res = -PSICONV_E_NOMEM;
438 goto ERROR2;
439 }
440 if (!(next1 = psiconv_list_get(plain_bytes,i+2))) {
441 res = -PSICONV_E_NOMEM;
442 goto ERROR2;
443 }
444 if (!(next2 = psiconv_list_get(plain_bytes,i+3))) {
445 res = -PSICONV_E_NOMEM;
446 goto ERROR2;
447 }
448 if (i == psiconv_list_length(plain_bytes) - 4) {
449 temp = 0xfe;
450 if ((res = psiconv_list_add(*encoded_bytes,&temp)))
451 goto ERROR2;
452 if ((res = psiconv_list_add(*encoded_bytes,entry1)))
453 goto ERROR2;
454 if ((res = psiconv_list_add(*encoded_bytes,entry2)))
455 goto ERROR2;
456 if ((res = psiconv_list_add(*encoded_bytes,next1)))
457 goto ERROR2;
458 if ((res = psiconv_list_add(*encoded_bytes,next2)))
459 goto ERROR2;
460 i +=4;
461 } else if ((*next1 == *entry1) && (*next2 == *entry2)) {
462 len = 0;
463 while (((*next1 == *entry1) && (*next2 == *entry2)) &&
464 (i+2*len + 4 < psiconv_list_length(plain_bytes)) &&
465 len < 0x80) {
466 len ++;
467 if (!(next1 = psiconv_list_get(plain_bytes,i+len*2))) {
468 res = -PSICONV_E_NOMEM;
469 goto ERROR2;
470 }
471 if (!(next2 = psiconv_list_get(plain_bytes,i+len*2+1))) {
472 res = -PSICONV_E_NOMEM;
473 goto ERROR2;
474 }
475 }
476 temp = len - 1;
477 if ((res = psiconv_list_add(*encoded_bytes,&temp)))
478 goto ERROR2;
479 if ((res = psiconv_list_add(*encoded_bytes,entry1)))
480 goto ERROR2;
481 if ((res = psiconv_list_add(*encoded_bytes,entry2)))
482 goto ERROR2;
483 i += len*2;
484 } else {
485 len = 1;
486 while (((*next1 != *entry1) || (*next2 != *entry2))&&
487 (i+len*2+4 < psiconv_list_length(plain_bytes)) &&
488 len < 0x80) {
489 len ++;
490 entry1 = next1;
491 entry2 = next2;
492 if (!(next1 = psiconv_list_get(plain_bytes,i+len*2))) {
493 res = -PSICONV_E_NOMEM;
494 goto ERROR2;
495 }
496 if (!(next2 = psiconv_list_get(plain_bytes,i+len*2+1))) {
497 res = -PSICONV_E_NOMEM;
498 goto ERROR2;
499 }
500 }
501 len --;
502 temp = 0x100 - len;
503 if ((res = psiconv_list_add(*encoded_bytes,&temp)))
504 goto ERROR2;
505 for (j = 0; j < len; j++) {
506 if (!(next1 = psiconv_list_get(plain_bytes,i+j*2))) {
507 res = -PSICONV_E_NOMEM;
508 goto ERROR2;
509 }
510 if (!(next2 = psiconv_list_get(plain_bytes,i+j*2+1))) {
511 res = -PSICONV_E_NOMEM;
512 goto ERROR2;
513 }
514 if ((res = psiconv_list_add(*encoded_bytes,next1)))
515 goto ERROR2;
516 if ((res = psiconv_list_add(*encoded_bytes,next2)))
517 goto ERROR2;
518 }
519 i += len*2;
520 }
521 }
522 return 0;
523
524ERROR2:
525 psiconv_list_free(*encoded_bytes);
526ERROR1:
527 return res;
528}
529
530int psiconv_encode_rle24(const psiconv_config config,
531 const psiconv_pixel_bytes plain_bytes,
532 psiconv_pixel_bytes *encoded_bytes)
533{
534 int res,i,j,len;
535 psiconv_u8 *entry1,*entry2,*entry3,*next1,*next2,*next3;
536 psiconv_u8 temp;
537
538 if (!(*encoded_bytes = psiconv_list_new(sizeof(*entry1)))) {
539 res = -PSICONV_E_NOMEM;
540 goto ERROR1;
541 }
542
543 for (i = 0; i < psiconv_list_length(plain_bytes);) {
544 if (!(entry1 = psiconv_list_get(plain_bytes,i))) {
545 res = -PSICONV_E_NOMEM;
546 goto ERROR2;
547 }
548 if (!(entry2 = psiconv_list_get(plain_bytes,i+1))) {
549 res = -PSICONV_E_NOMEM;
550 goto ERROR2;
551 }
552 if (!(entry3 = psiconv_list_get(plain_bytes,i+2))) {
553 res = -PSICONV_E_NOMEM;
554 goto ERROR2;
555 }
556 if (!(next1 = psiconv_list_get(plain_bytes,i+3))) {
557 res = -PSICONV_E_NOMEM;
558 goto ERROR2;
559 }
560 if (!(next2 = psiconv_list_get(plain_bytes,i+4))) {
561 res = -PSICONV_E_NOMEM;
562 goto ERROR2;
563 }
564 if (!(next3 = psiconv_list_get(plain_bytes,i+5))) {
565 res = -PSICONV_E_NOMEM;
566 goto ERROR2;
567 }
568 if (i == psiconv_list_length(plain_bytes) - 6) {
569 temp = 0xfe;
570 if ((res = psiconv_list_add(*encoded_bytes,&temp)))
571 goto ERROR2;
572 if ((res = psiconv_list_add(*encoded_bytes,entry1)))
573 goto ERROR2;
574 if ((res = psiconv_list_add(*encoded_bytes,entry2)))
575 goto ERROR2;
576 if ((res = psiconv_list_add(*encoded_bytes,entry3)))
577 goto ERROR2;
578 if ((res = psiconv_list_add(*encoded_bytes,next1)))
579 goto ERROR2;
580 if ((res = psiconv_list_add(*encoded_bytes,next2)))
581 goto ERROR2;
582 if ((res = psiconv_list_add(*encoded_bytes,next3)))
583 goto ERROR2;
584 i +=4;
585 } else if ((*next1 == *entry1) && (*next2 == *entry2) &&
586 (*next3 == *entry3)) {
587 len = 0;
588 while (((*next1 == *entry1) && (*next2 == *entry2) &&
589 (*next3 == *entry3)) &&
590 (i+3*len + 6 < psiconv_list_length(plain_bytes)) &&
591 len < 0x80) {
592 len ++;
593 if (!(next1 = psiconv_list_get(plain_bytes,i+len*3))) {
594 res = -PSICONV_E_NOMEM;
595 goto ERROR2;
596 }
597 if (!(next2 = psiconv_list_get(plain_bytes,i+len*3+1))) {
598 res = -PSICONV_E_NOMEM;
599 goto ERROR2;
600 }
601 if (!(next3 = psiconv_list_get(plain_bytes,i+len*3+2))) {
602 res = -PSICONV_E_NOMEM;
603 goto ERROR2;
604 }
605 }
606 temp = len - 1;
607 if ((res = psiconv_list_add(*encoded_bytes,&temp)))
608 goto ERROR2;
609 if ((res = psiconv_list_add(*encoded_bytes,entry1)))
610 goto ERROR2;
611 if ((res = psiconv_list_add(*encoded_bytes,entry2)))
612 goto ERROR2;
613 if ((res = psiconv_list_add(*encoded_bytes,entry3)))
614 goto ERROR2;
615 i += len*3;
616 } else {
617 len = 1;
618 while (((*next1 != *entry1) || (*next2 != *entry2) ||
619 (*next3 != *entry3)) &&
620 (i+len*3+6 < psiconv_list_length(plain_bytes)) &&
621 len < 0x80) {
622 len ++;
623 entry1 = next1;
624 entry2 = next2;
625 entry3 = next3;
626 if (!(next1 = psiconv_list_get(plain_bytes,i+len*3))) {
627 res = -PSICONV_E_NOMEM;
628 goto ERROR2;
629 }
630 if (!(next2 = psiconv_list_get(plain_bytes,i+len*3+1))) {
631 res = -PSICONV_E_NOMEM;
632 goto ERROR2;
633 }
634 if (!(next3 = psiconv_list_get(plain_bytes,i+len*3+2))) {
635 res = -PSICONV_E_NOMEM;
636 goto ERROR2;
637 }
638 }
639 len --;
640 temp = 0x100 - len;
641 if ((res = psiconv_list_add(*encoded_bytes,&temp)))
642 goto ERROR2;
643 for (j = 0; j < len; j++) {
644 if (!(next1 = psiconv_list_get(plain_bytes,i+j*3))) {
645 res = -PSICONV_E_NOMEM;
646 goto ERROR2;
647 }
648 if (!(next2 = psiconv_list_get(plain_bytes,i+j*3+1))) {
649 res = -PSICONV_E_NOMEM;
650 goto ERROR2;
651 }
652 if (!(next2 = psiconv_list_get(plain_bytes,i+j*3+2))) {
653 res = -PSICONV_E_NOMEM;
654 goto ERROR2;
655 }
656 if ((res = psiconv_list_add(*encoded_bytes,next1)))
657 goto ERROR2;
658 if ((res = psiconv_list_add(*encoded_bytes,next2)))
659 goto ERROR2;
660 if ((res = psiconv_list_add(*encoded_bytes,next3)))
661 goto ERROR2;
662 }
663 i += len*3;
664 }
665 }
666 return 0;
667
668ERROR2:
669 psiconv_list_free(*encoded_bytes);
670ERROR1:
671 return res;
672}
673
674
675int psiconv_write_sketch_section(const psiconv_config config,
676 psiconv_buffer buf,
677 const psiconv_sketch_section value)
678{
679 int res;
680
681 if (!value) {
682 psiconv_warn(config,0,0,"NULL sketch section");
683 res = -PSICONV_E_GENERATE;
684 goto ERROR1;
685 }
686
687 if ((res = psiconv_write_u16(config,buf,value->displayed_xsize)))
688 goto ERROR1;
689 if ((res = psiconv_write_u16(config,buf,value->displayed_ysize)))
690 goto ERROR1;
691 if ((res = psiconv_write_u16(config,buf,value->picture_data_x_offset)))
692 goto ERROR1;
693 if ((res = psiconv_write_u16(config,buf,value->picture_data_y_offset)))
694 goto ERROR1;
695 if ((res = psiconv_write_u16(config,buf,value->displayed_size_x_offset)))
696 goto ERROR1;
697 if ((res = psiconv_write_u16(config,buf,value->displayed_size_y_offset)))
698 goto ERROR1;
699 if ((res = psiconv_write_u16(config,buf,value->form_xsize)))
700 goto ERROR1;
701 if ((res = psiconv_write_u16(config,buf,value->form_ysize)))
702 goto ERROR1;
703 if ((res = psiconv_write_u16(config,buf,0x0000)))
704 goto ERROR1;
705 if ((res = psiconv_write_paint_data_section(config,buf,value->picture,0)))
706 goto ERROR1;
707 if ((res = psiconv_write_u16(config,buf,value->magnification_x * 0x03e8)))
708 goto ERROR1;
709 if ((res = psiconv_write_u16(config,buf,value->magnification_y * 0x03e8)))
710 goto ERROR1;
711 if ((res = psiconv_write_u32(config,buf,value->cut_left * 0x0c *
712 value->displayed_xsize)))
713 goto ERROR1;
714 if ((res = psiconv_write_u32(config,buf,value->cut_right * 0x0c *
715 value->displayed_xsize)))
716 goto ERROR1;
717 if ((res = psiconv_write_u32(config,buf,value->cut_top * 0x0c *
718 value->displayed_ysize)))
719 goto ERROR1;
720 if ((res = psiconv_write_u32(config,buf,value->cut_bottom * 0x0c *
721 value->displayed_ysize)))
722 goto ERROR1;
723
724ERROR1:
725 return res;
726}
727
728int psiconv_write_clipart_section(const psiconv_config config,
729 psiconv_buffer buf,
730 const psiconv_clipart_section value)
731{
732 int res;
733
734
735 if (!value) {
736 psiconv_warn(config,0,psiconv_buffer_length(buf),
737 "NULL Clipart Section");
738 res = -PSICONV_E_GENERATE;
739 goto ERROR;
740 }
741 if ((res = psiconv_write_u32(config,buf,PSICONV_ID_CLIPART_ITEM)))
742 goto ERROR;
743 if ((res = psiconv_write_u32(config,buf,0x00000002)))
744 goto ERROR;
745 if ((res = psiconv_write_u32(config,buf,0x00000000)))
746 goto ERROR;
747 if ((res = psiconv_write_u32(config,buf,0x00000000)))
748 goto ERROR;
749 if ((res = psiconv_write_u32(config,buf,0x0000000C)))
750 goto ERROR;
751 if ((res = psiconv_write_paint_data_section(config,buf,value->picture,1)))
752 goto ERROR;
753
754ERROR:
755 return res;
756}
757
758int psiconv_write_jumptable_section(const psiconv_config config,
759 psiconv_buffer buf,
760 const psiconv_jumptable_section value)
761{
762 int res,i;
763 psiconv_u32 *offset_ptr;
764
765
766 if (!value) {
767 psiconv_warn(config,0,psiconv_buffer_length(buf),
768 "NULL Jumptable Section");
769 res = -PSICONV_E_GENERATE;
770 goto ERROR;
771 }
772 if ((res = psiconv_write_u32(config,buf,psiconv_list_length(value))))
773 goto ERROR;
774 for (i = 0; i < psiconv_list_length(value); i++) {
775 if (!(offset_ptr = psiconv_list_get(value,i))) {
776 psiconv_warn(config,0,psiconv_buffer_length(buf),
777 "Massive memory corruption");
778 res = -PSICONV_E_NOMEM;
779 goto ERROR;
780 }
781 if ((res = psiconv_write_offset(config,buf,*offset_ptr)))
782 goto ERROR;
783 }
784
785ERROR:
786 return res;
787}
788

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

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