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

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

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

Revision 179 Revision 348
1/* 1/*
2 parse_image.c - Part of psiconv, a PSION 5 file formats converter 2 parse_image.c - Part of psiconv, a PSION 5 file formats converter
3 Copyright (c) 1999, 2000 Frodo Looijaard <frodol@dds.nl> 3 Copyright (c) 1999-2005 Frodo Looijaard <frodo@frodo.looijaard.name>
4 4
5 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
6 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
7 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version. 8 (at your option) any later version.
27#include "image.h" 27#include "image.h"
28 28
29#ifdef DMALLOC 29#ifdef DMALLOC
30#include <dmalloc.h> 30#include <dmalloc.h>
31#endif 31#endif
32
33/* Extreme debugging info */
34#undef LOUD
32 35
33static int psiconv_decode_rle8 (const psiconv_config config, int lev, 36static int psiconv_decode_rle8 (const psiconv_config config, int lev,
34 psiconv_u32 off, 37 psiconv_u32 off,
35 const psiconv_pixel_bytes encoded, 38 const psiconv_pixel_bytes encoded,
36 psiconv_pixel_bytes *decoded); 39 psiconv_pixel_bytes *decoded);
107 return 0; 110 return 0;
108 111
109ERROR2: 112ERROR2:
110 psiconv_list_free(*result); 113 psiconv_list_free(*result);
111ERROR1: 114ERROR1:
112 psiconv_warn(config,lev+1,off,"Reading of Jumptable Section failed"); 115 psiconv_error(config,lev+1,off,"Reading of Jumptable Section failed");
113 if (length) 116 if (length)
114 *length = 0; 117 *length = 0;
115 if (!res) 118 if (!res)
116 return -PSICONV_E_NOMEM; 119 return -PSICONV_E_NOMEM;
117 else 120 else
123 psiconv_u32 off, int *length,int isclipart, 126 psiconv_u32 off, int *length,int isclipart,
124 psiconv_paint_data_section *result) 127 psiconv_paint_data_section *result)
125{ 128{
126 int res = 0; 129 int res = 0;
127 int len = 0; 130 int len = 0;
128 psiconv_u32 size,offset,picsize,temp,datasize,color, 131 psiconv_u32 size,offset,temp,datasize,color,
129 redbits,bluebits,greenbits; 132 redbits,bluebits,greenbits;
130 psiconv_u8 byte; 133 psiconv_u8 byte;
131 int leng,i; 134 int leng,i;
132 psiconv_u32 bits_per_pixel,compression; 135 psiconv_u32 bits_per_pixel,compression;
133 psiconv_pixel_bytes bytes,decoded; 136 psiconv_pixel_bytes bytes,decoded;
151 psiconv_progress(config,lev+2,off+len,"Going to read pixel data offset"); 154 psiconv_progress(config,lev+2,off+len,"Going to read pixel data offset");
152 offset = psiconv_read_u32(config,buf,lev+2,off+len,&res); 155 offset = psiconv_read_u32(config,buf,lev+2,off+len,&res);
153 if (res) 156 if (res)
154 goto ERROR3; 157 goto ERROR3;
155 if (offset != 0x28) { 158 if (offset != 0x28) {
156 psiconv_warn(config,lev+2,off+len, 159 psiconv_error(config,lev+2,off+len,
157 "Paint data section data offset has unexpected value"); 160 "Paint data section data offset has unexpected value");
158 psiconv_debug(config,lev+2,off+len, 161 psiconv_debug(config,lev+2,off+len,
159 "Data offset: read %08x, expected %08x",offset,0x28); 162 "Data offset: read %08x, expected %08x",offset,0x28);
160 res = -1; 163 res = -1;
161 } 164 }
172 (*result)->ysize = psiconv_read_u32(config,buf,lev+2,off+len,&res); 175 (*result)->ysize = psiconv_read_u32(config,buf,lev+2,off+len,&res);
173 if (res) 176 if (res)
174 goto ERROR3; 177 goto ERROR3;
175 psiconv_debug(config,lev+2,off+len,"Picture Y size: %08x:",(*result)->ysize); 178 psiconv_debug(config,lev+2,off+len,"Picture Y size: %08x:",(*result)->ysize);
176 len += 4; 179 len += 4;
177
178 picsize = (*result)->ysize * (*result)->xsize;
179 180
180 psiconv_progress(config,lev+2,off+len,"Going to read the real picture x size"); 181 psiconv_progress(config,lev+2,off+len,"Going to read the real picture x size");
181 (*result)->pic_xsize = psiconv_read_length(config,buf,lev+2,off+len,&leng,&res); 182 (*result)->pic_xsize = psiconv_read_length(config,buf,lev+2,off+len,&leng,&res);
182 if (res) 183 if (res)
183 goto ERROR3; 184 goto ERROR3;
277 "All image types except 2-bit greyscale are experimental!"); 278 "All image types except 2-bit greyscale are experimental!");
278 279
279 psiconv_progress(config,lev+2,off+len,"Going to read the pixel data"); 280 psiconv_progress(config,lev+2,off+len,"Going to read the pixel data");
280 for (i = 0; i < datasize; i++) { 281 for (i = 0; i < datasize; i++) {
281 byte = psiconv_read_u8(config,buf,lev+2,off+len+i,&res); 282 byte = psiconv_read_u8(config,buf,lev+2,off+len+i,&res);
283#ifdef LOUD
282 psiconv_debug(config,lev+2,off+len+i, 284 psiconv_debug(config,lev+2,off+len+i,
283 "Pixel byte %04x of %04x has value %02x", 285 "Pixel byte %04x of %04x has value %02x",
284 i,datasize,byte); 286 i,datasize,byte);
287#endif
285 if (res) 288 if (res)
286 goto ERROR3; 289 goto ERROR3;
287 psiconv_list_add(bytes,&byte); 290 psiconv_list_add(bytes,&byte);
288 } 291 }
289 len += datasize; 292 len += datasize;
360ERROR3: 363ERROR3:
361 psiconv_list_free(bytes); 364 psiconv_list_free(bytes);
362ERROR2: 365ERROR2:
363 free(*result); 366 free(*result);
364ERROR1: 367ERROR1:
365 psiconv_warn(config,lev+1,off,"Reading of Paint Data Section failed"); 368 psiconv_error(config,lev+1,off,"Reading of Paint Data Section failed");
366 if (length) 369 if (length)
367 *length = 0; 370 *length = 0;
368 if (!res) 371 if (!res)
369 return -PSICONV_E_NOMEM; 372 return -PSICONV_E_NOMEM;
370 else 373 else
525ERROR3: 528ERROR3:
526 psiconv_free_paint_data_section((*result)->picture); 529 psiconv_free_paint_data_section((*result)->picture);
527ERROR2: 530ERROR2:
528 free (*result); 531 free (*result);
529ERROR1: 532ERROR1:
530 psiconv_warn(config,lev+1,off,"Reading of Sketch Section failed"); 533 psiconv_error(config,lev+1,off,"Reading of Sketch Section failed");
531 if (length) 534 if (length)
532 *length = 0; 535 *length = 0;
533 if (!res) 536 if (!res)
534 return -PSICONV_E_NOMEM; 537 return -PSICONV_E_NOMEM;
535 else 538 else
628 return 0; 631 return 0;
629 632
630ERROR2: 633ERROR2:
631 free (*result); 634 free (*result);
632ERROR1: 635ERROR1:
633 psiconv_warn(config,lev+1,off,"Reading of Font failed"); 636 psiconv_error(config,lev+1,off,"Reading of Font failed");
634 if (length) 637 if (length)
635 *length = 0; 638 *length = 0;
636 if (!res) 639 if (!res)
637 return -PSICONV_E_NOMEM; 640 return -PSICONV_E_NOMEM;
638 else 641 else
650 psiconv_progress(config,lev+1,off,"Going to decode the RLE8 encoding"); 653 psiconv_progress(config,lev+1,off,"Going to decode the RLE8 encoding");
651 if (!(*decoded = psiconv_list_new(sizeof(psiconv_u8)))) 654 if (!(*decoded = psiconv_list_new(sizeof(psiconv_u8))))
652 goto ERROR1; 655 goto ERROR1;
653 656
654 for (i = 0; i < psiconv_list_length(encoded);) { 657 for (i = 0; i < psiconv_list_length(encoded);) {
658#ifdef LOUD
655 psiconv_progress(config,lev+2,off,"Going to read marker byte at %04x",i); 659 psiconv_progress(config,lev+2,off,"Going to read marker byte at %04x",i);
660#endif
656 if (!(marker = psiconv_list_get(encoded,i))) 661 if (!(marker = psiconv_list_get(encoded,i)))
657 goto ERROR2; 662 goto ERROR2;
663#ifdef LOUD
658 psiconv_debug(config,lev+2,off,"Marker byte: %02x",*marker); 664 psiconv_debug(config,lev+2,off,"Marker byte: %02x",*marker);
665#endif
659 if (*marker < 0x80) { 666 if (*marker < 0x80) {
667#ifdef LOUD
660 psiconv_debug(config,lev+2,off,"Marker: repeat value byte %02x times", 668 psiconv_debug(config,lev+2,off,"Marker: repeat value byte %02x times",
661 *marker+1); 669 *marker+1); */
662 psiconv_progress(config,lev+2,off,"Going to read value byte at %04x",i+1); 670 psiconv_progress(config,lev+2,off,"Going to read value byte at %04x",i+1);
671#endif
663 if (!(value = psiconv_list_get(encoded,i+1))) 672 if (!(value = psiconv_list_get(encoded,i+1)))
664 goto ERROR2; 673 goto ERROR2;
674#ifdef LOUD
665 psiconv_debug(config,lev+2,off,"Value byte: %02x",*value); 675 psiconv_debug(config,lev+2,off,"Value byte: %02x",*value);
666 psiconv_progress(config,lev+2,off,"Adding %02x pixels %02x", 676 psiconv_progress(config,lev+2,off,"Adding %02x pixels %02x",
667 *marker+1,*value); 677 *marker+1,*value);
678#endif
668 for (j = 0; j < *marker + 1; j++) 679 for (j = 0; j < *marker + 1; j++)
669 if ((res = psiconv_list_add(*decoded,value))) 680 if ((res = psiconv_list_add(*decoded,value)))
670 goto ERROR2; 681 goto ERROR2;
671 i += 2; 682 i += 2;
672 } else { 683 } else {
684#ifdef LOUD
673 psiconv_debug(config,lev+2,off,"Marker: %02x value bytes follow", 685 psiconv_debug(config,lev+2,off,"Marker: %02x value bytes follow",
674 0x100 - *marker); 686 0x100 - *marker);
687#endif
675 for (j = 0; j < (0x100 - *marker); j++) { 688 for (j = 0; j < (0x100 - *marker); j++) {
689#ifdef LOUD
676 psiconv_progress(config,lev+2,off,"Going to read value byte at %04x", 690 psiconv_progress(config,lev+2,off,"Going to read value byte at %04x",
677 i+j+1); 691 i+j+1);
692#endif
678 if (!(value = psiconv_list_get(encoded,i+j+1))) 693 if (!(value = psiconv_list_get(encoded,i+j+1)))
679 goto ERROR2; 694 goto ERROR2;
695#ifdef LOUD
680 psiconv_debug(config,lev+2,off,"Value: %02x",*value); 696 psiconv_debug(config,lev+2,off,"Value: %02x",*value);
697#endif
681 if ((res = psiconv_list_add(*decoded,value))) 698 if ((res = psiconv_list_add(*decoded,value)))
682 goto ERROR2; 699 goto ERROR2;
683 } 700 }
684 i += (0x100 - *marker) + 1; 701 i += (0x100 - *marker) + 1;
685 } 702 }
689 return 0; 706 return 0;
690 707
691ERROR2: 708ERROR2:
692 psiconv_list_free(*decoded); 709 psiconv_list_free(*decoded);
693ERROR1: 710ERROR1:
694 psiconv_warn(config,lev+1,off,"Decoding of RLE8 failed"); 711 psiconv_error(config,lev+1,off,"Decoding of RLE8 failed");
695 if (!res) 712 if (!res)
696 return -PSICONV_E_NOMEM; 713 return -PSICONV_E_NOMEM;
697 else 714 else
698 return res; 715 return res;
699} 716}
732 return 0; 749 return 0;
733 750
734ERROR2: 751ERROR2:
735 psiconv_list_free(*decoded); 752 psiconv_list_free(*decoded);
736ERROR1: 753ERROR1:
737 psiconv_warn(config,lev+1,off,"Decoding of RLE12 failed"); 754 psiconv_error(config,lev+1,off,"Decoding of RLE12 failed");
738 if (!res) 755 if (!res)
739 return -PSICONV_E_NOMEM; 756 return -PSICONV_E_NOMEM;
740 else 757 else
741 return res; 758 return res;
742} 759}
798 return 0; 815 return 0;
799 816
800ERROR2: 817ERROR2:
801 psiconv_list_free(*decoded); 818 psiconv_list_free(*decoded);
802ERROR1: 819ERROR1:
803 psiconv_warn(config,lev+1,off,"Decoding of RLE16 failed"); 820 psiconv_error(config,lev+1,off,"Decoding of RLE16 failed");
804 if (!res) 821 if (!res)
805 return -PSICONV_E_NOMEM; 822 return -PSICONV_E_NOMEM;
806 else 823 else
807 return res; 824 return res;
808} 825}
868 return 0; 885 return 0;
869 886
870ERROR2: 887ERROR2:
871 psiconv_list_free(*decoded); 888 psiconv_list_free(*decoded);
872ERROR1: 889ERROR1:
873 psiconv_warn(config,lev+1,off,"Decoding of RLE24 failed"); 890 psiconv_error(config,lev+1,off,"Decoding of RLE24 failed");
874 if (!res) 891 if (!res)
875 return -PSICONV_E_NOMEM; 892 return -PSICONV_E_NOMEM;
876 else 893 else
877 return res; 894 return res;
878} 895}
899 while (nr % 4) 916 while (nr % 4)
900 nr ++; 917 nr ++;
901 input = 0; 918 input = 0;
902 ibits = 0; 919 ibits = 0;
903 for (x= 0; x < xsize; x++) { 920 for (x= 0; x < xsize; x++) {
921#ifdef LOUD
904 psiconv_progress(config,lev+2,off, 922 psiconv_progress(config,lev+2,off,
905 "Processing pixel at (x,y) = (%04x,%04x)",x,y); 923 "Processing pixel at (x,y) = (%04x,%04x)",x,y);
924#endif
906 output = 0; 925 output = 0;
907 obits = 0; 926 obits = 0;
908 while (obits < colordepth) { 927 while (obits < colordepth) {
909 if (ibits == 0) { 928 if (ibits == 0) {
929#ifdef LOUD
910 psiconv_progress(config,lev+3,off, 930 psiconv_progress(config,lev+3,off,
911 "Going to read byte %08x",nr); 931 "Going to read byte %08x",nr);
932#endif
912 if (!(ientry = psiconv_list_get(bytes,nr))) 933 if (!(ientry = psiconv_list_get(bytes,nr)))
913 goto ERROR2; 934 goto ERROR2;
935#ifdef LOUD
914 psiconv_debug(config,lev+3,off,"Byte value: %02x",*ientry); 936 psiconv_debug(config,lev+3,off,"Byte value: %02x",*ientry);
937#endif
915 input = *ientry; 938 input = *ientry;
916 ibits = 8; 939 ibits = 8;
917 nr ++; 940 nr ++;
918 } 941 }
919 bits = ibits + obits > colordepth?colordepth-obits:ibits; 942 bits = ibits + obits > colordepth?colordepth-obits:ibits;
921 output |= input & ((1 << bits) - 1); 944 output |= input & ((1 << bits) - 1);
922 input = input >> bits; 945 input = input >> bits;
923 ibits -= bits; 946 ibits -= bits;
924 obits += bits; 947 obits += bits;
925 } 948 }
949#ifdef LOUD
926 psiconv_debug(config,lev+2,off,"Pixel value: %08x",output); 950 psiconv_debug(config,lev+2,off,"Pixel value: %08x",output);
951#endif
927 if ((res = psiconv_list_add(*pixels,&output))) 952 if ((res = psiconv_list_add(*pixels,&output)))
928 goto ERROR2; 953 goto ERROR2;
929 } 954 }
930 } 955 }
931 956
935 960
936 961
937ERROR2: 962ERROR2:
938 psiconv_list_free(*pixels); 963 psiconv_list_free(*pixels);
939ERROR1: 964ERROR1:
940 psiconv_warn(config,lev+1,off,"Converting bytes to pixels failed"); 965 psiconv_error(config,lev+1,off,"Converting bytes to pixels failed");
941 if (!res) 966 if (!res)
942 return -PSICONV_E_NOMEM; 967 return -PSICONV_E_NOMEM;
943 else 968 else
944 return res; 969 return res;
945} 970}
969 (*floats).length = psiconv_list_length(pixels); 994 (*floats).length = psiconv_list_length(pixels);
970 995
971 for (i = 0; i < psiconv_list_length(pixels); i++) { 996 for (i = 0; i < psiconv_list_length(pixels); i++) {
972 if (!(pixel = psiconv_list_get(pixels,i))) 997 if (!(pixel = psiconv_list_get(pixels,i)))
973 goto ERROR4; 998 goto ERROR4;
999#ifdef LOUD
974 psiconv_progress(config,lev+2,off, "Handling pixel %04x (%04x)",i,*pixel); 1000 psiconv_progress(config,lev+2,off, "Handling pixel %04x (%04x)",i,*pixel);
1001#endif
975 if (!palet.length) { 1002 if (!palet.length) {
976 if (color) { 1003 if (color) {
977 (*floats).blue[i] = ((float) (*pixel & ((1 << bluebits) - 1))) / 1004 (*floats).blue[i] = ((float) (*pixel & ((1 << bluebits) - 1))) /
978 (1 << bluebits); 1005 ((1 << bluebits) - 1);
979 (*floats).green[i] = ((float) ((*pixel >> bluebits) & 1006 (*floats).green[i] = ((float) ((*pixel >> bluebits) &
980 ((1 << greenbits) - 1))) / (1 << greenbits); 1007 ((1 << greenbits) - 1))) / ((1 << greenbits) - 1);
981 (*floats).red[i] = ((float) ((*pixel >> (bluebits+greenbits)) & 1008 (*floats).red[i] = ((float) ((*pixel >> (bluebits+greenbits)) &
982 ((1 << redbits) - 1))) / (1 << redbits); 1009 ((1 << redbits) - 1))) / ((1 << redbits) - 1);
983 } else { 1010 } else {
984 (*floats).red[i] = (*floats).green[i] = 1011 (*floats).red[i] = (*floats).green[i] =
985 (*floats).blue[i] = ((float) *pixel) / 1012 (*floats).blue[i] = ((float) *pixel) /
986 (1 << colordepth); 1013 ((1 << colordepth) - 1);
987 } 1014 }
988 } else { 1015 } else {
989 if (*pixel >= palet.length) { 1016 if (*pixel >= palet.length) {
990 psiconv_warn(config,lev+2,off, 1017 psiconv_warn(config,lev+2,off,
991 "Invalid palet color found (using color 0x00)"); 1018 "Invalid palet color found (using color 0x00)");
996 (*floats).red[i] = palet.red[*pixel]; 1023 (*floats).red[i] = palet.red[*pixel];
997 (*floats).green[i] = palet.green[*pixel]; 1024 (*floats).green[i] = palet.green[*pixel];
998 (*floats).blue[i] = palet.blue[*pixel]; 1025 (*floats).blue[i] = palet.blue[*pixel];
999 } 1026 }
1000 } 1027 }
1028#ifdef LOUD
1001 psiconv_debug(config,lev+2,off, "Pixel: Red (%f), green (%f), blue (%f)", 1029 psiconv_debug(config,lev+2,off, "Pixel: Red (%f), green (%f), blue (%f)",
1002 (*floats).red[i],(*floats).green[i],(*floats).blue[i]); 1030 (*floats).red[i],(*floats).green[i],(*floats).blue[i]);
1031#endif
1003 } 1032 }
1004 psiconv_progress(config,lev+1,off,"Finished converting pixels to floats"); 1033 psiconv_progress(config,lev+1,off,"Finished converting pixels to floats");
1005 return 0; 1034 return 0;
1006 1035
1007ERROR4: 1036ERROR4:
1009ERROR3: 1038ERROR3:
1010 free((*floats).green); 1039 free((*floats).green);
1011ERROR2: 1040ERROR2:
1012 free((*floats).red); 1041 free((*floats).red);
1013ERROR1: 1042ERROR1:
1014 psiconv_warn(config,lev+1,off,"Converting pixels to floats failed"); 1043 psiconv_error(config,lev+1,off,"Converting pixels to floats failed");
1015 if (!res) 1044 if (!res)
1016 return -PSICONV_E_NOMEM; 1045 return -PSICONV_E_NOMEM;
1017 else 1046 else
1018 return res; 1047 return res;
1019} 1048}

Legend:
Removed from v.179  
changed lines
  Added in v.348

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