/[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 230
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-2004 Frodo Looijaard <frodol@dds.nl>
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
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 }
277 "All image types except 2-bit greyscale are experimental!"); 280 "All image types except 2-bit greyscale are experimental!");
278 281
279 psiconv_progress(config,lev+2,off+len,"Going to read the pixel data"); 282 psiconv_progress(config,lev+2,off+len,"Going to read the pixel data");
280 for (i = 0; i < datasize; i++) { 283 for (i = 0; i < datasize; i++) {
281 byte = psiconv_read_u8(config,buf,lev+2,off+len+i,&res); 284 byte = psiconv_read_u8(config,buf,lev+2,off+len+i,&res);
285#ifdef LOUD
282 psiconv_debug(config,lev+2,off+len+i, 286 psiconv_debug(config,lev+2,off+len+i,
283 "Pixel byte %04x of %04x has value %02x", 287 "Pixel byte %04x of %04x has value %02x",
284 i,datasize,byte); 288 i,datasize,byte);
289#endif
285 if (res) 290 if (res)
286 goto ERROR3; 291 goto ERROR3;
287 psiconv_list_add(bytes,&byte); 292 psiconv_list_add(bytes,&byte);
288 } 293 }
289 len += datasize; 294 len += datasize;
360ERROR3: 365ERROR3:
361 psiconv_list_free(bytes); 366 psiconv_list_free(bytes);
362ERROR2: 367ERROR2:
363 free(*result); 368 free(*result);
364ERROR1: 369ERROR1:
365 psiconv_warn(config,lev+1,off,"Reading of Paint Data Section failed"); 370 psiconv_error(config,lev+1,off,"Reading of Paint Data Section failed");
366 if (length) 371 if (length)
367 *length = 0; 372 *length = 0;
368 if (!res) 373 if (!res)
369 return -PSICONV_E_NOMEM; 374 return -PSICONV_E_NOMEM;
370 else 375 else
525ERROR3: 530ERROR3:
526 psiconv_free_paint_data_section((*result)->picture); 531 psiconv_free_paint_data_section((*result)->picture);
527ERROR2: 532ERROR2:
528 free (*result); 533 free (*result);
529ERROR1: 534ERROR1:
530 psiconv_warn(config,lev+1,off,"Reading of Sketch Section failed"); 535 psiconv_error(config,lev+1,off,"Reading of Sketch Section failed");
531 if (length) 536 if (length)
532 *length = 0; 537 *length = 0;
533 if (!res) 538 if (!res)
534 return -PSICONV_E_NOMEM; 539 return -PSICONV_E_NOMEM;
535 else 540 else
628 return 0; 633 return 0;
629 634
630ERROR2: 635ERROR2:
631 free (*result); 636 free (*result);
632ERROR1: 637ERROR1:
633 psiconv_warn(config,lev+1,off,"Reading of Font failed"); 638 psiconv_error(config,lev+1,off,"Reading of Font failed");
634 if (length) 639 if (length)
635 *length = 0; 640 *length = 0;
636 if (!res) 641 if (!res)
637 return -PSICONV_E_NOMEM; 642 return -PSICONV_E_NOMEM;
638 else 643 else
650 psiconv_progress(config,lev+1,off,"Going to decode the RLE8 encoding"); 655 psiconv_progress(config,lev+1,off,"Going to decode the RLE8 encoding");
651 if (!(*decoded = psiconv_list_new(sizeof(psiconv_u8)))) 656 if (!(*decoded = psiconv_list_new(sizeof(psiconv_u8))))
652 goto ERROR1; 657 goto ERROR1;
653 658
654 for (i = 0; i < psiconv_list_length(encoded);) { 659 for (i = 0; i < psiconv_list_length(encoded);) {
660#ifdef LOUD
655 psiconv_progress(config,lev+2,off,"Going to read marker byte at %04x",i); 661 psiconv_progress(config,lev+2,off,"Going to read marker byte at %04x",i);
662#endif
656 if (!(marker = psiconv_list_get(encoded,i))) 663 if (!(marker = psiconv_list_get(encoded,i)))
657 goto ERROR2; 664 goto ERROR2;
665#ifdef LOUD
658 psiconv_debug(config,lev+2,off,"Marker byte: %02x",*marker); 666 psiconv_debug(config,lev+2,off,"Marker byte: %02x",*marker);
667#endif
659 if (*marker < 0x80) { 668 if (*marker < 0x80) {
669#ifdef LOUD
660 psiconv_debug(config,lev+2,off,"Marker: repeat value byte %02x times", 670 psiconv_debug(config,lev+2,off,"Marker: repeat value byte %02x times",
661 *marker+1); 671 *marker+1); */
662 psiconv_progress(config,lev+2,off,"Going to read value byte at %04x",i+1); 672 psiconv_progress(config,lev+2,off,"Going to read value byte at %04x",i+1);
673#endif
663 if (!(value = psiconv_list_get(encoded,i+1))) 674 if (!(value = psiconv_list_get(encoded,i+1)))
664 goto ERROR2; 675 goto ERROR2;
676#ifdef LOUD
665 psiconv_debug(config,lev+2,off,"Value byte: %02x",*value); 677 psiconv_debug(config,lev+2,off,"Value byte: %02x",*value);
666 psiconv_progress(config,lev+2,off,"Adding %02x pixels %02x", 678 psiconv_progress(config,lev+2,off,"Adding %02x pixels %02x",
667 *marker+1,*value); 679 *marker+1,*value);
680#endif
668 for (j = 0; j < *marker + 1; j++) 681 for (j = 0; j < *marker + 1; j++)
669 if ((res = psiconv_list_add(*decoded,value))) 682 if ((res = psiconv_list_add(*decoded,value)))
670 goto ERROR2; 683 goto ERROR2;
671 i += 2; 684 i += 2;
672 } else { 685 } else {
686#ifdef LOUD
673 psiconv_debug(config,lev+2,off,"Marker: %02x value bytes follow", 687 psiconv_debug(config,lev+2,off,"Marker: %02x value bytes follow",
674 0x100 - *marker); 688 0x100 - *marker);
689#endif
675 for (j = 0; j < (0x100 - *marker); j++) { 690 for (j = 0; j < (0x100 - *marker); j++) {
691#ifdef LOUD
676 psiconv_progress(config,lev+2,off,"Going to read value byte at %04x", 692 psiconv_progress(config,lev+2,off,"Going to read value byte at %04x",
677 i+j+1); 693 i+j+1);
694#endif
678 if (!(value = psiconv_list_get(encoded,i+j+1))) 695 if (!(value = psiconv_list_get(encoded,i+j+1)))
679 goto ERROR2; 696 goto ERROR2;
697#ifdef LOUD
680 psiconv_debug(config,lev+2,off,"Value: %02x",*value); 698 psiconv_debug(config,lev+2,off,"Value: %02x",*value);
699#endif
681 if ((res = psiconv_list_add(*decoded,value))) 700 if ((res = psiconv_list_add(*decoded,value)))
682 goto ERROR2; 701 goto ERROR2;
683 } 702 }
684 i += (0x100 - *marker) + 1; 703 i += (0x100 - *marker) + 1;
685 } 704 }
689 return 0; 708 return 0;
690 709
691ERROR2: 710ERROR2:
692 psiconv_list_free(*decoded); 711 psiconv_list_free(*decoded);
693ERROR1: 712ERROR1:
694 psiconv_warn(config,lev+1,off,"Decoding of RLE8 failed"); 713 psiconv_error(config,lev+1,off,"Decoding of RLE8 failed");
695 if (!res) 714 if (!res)
696 return -PSICONV_E_NOMEM; 715 return -PSICONV_E_NOMEM;
697 else 716 else
698 return res; 717 return res;
699} 718}
732 return 0; 751 return 0;
733 752
734ERROR2: 753ERROR2:
735 psiconv_list_free(*decoded); 754 psiconv_list_free(*decoded);
736ERROR1: 755ERROR1:
737 psiconv_warn(config,lev+1,off,"Decoding of RLE12 failed"); 756 psiconv_error(config,lev+1,off,"Decoding of RLE12 failed");
738 if (!res) 757 if (!res)
739 return -PSICONV_E_NOMEM; 758 return -PSICONV_E_NOMEM;
740 else 759 else
741 return res; 760 return res;
742} 761}
798 return 0; 817 return 0;
799 818
800ERROR2: 819ERROR2:
801 psiconv_list_free(*decoded); 820 psiconv_list_free(*decoded);
802ERROR1: 821ERROR1:
803 psiconv_warn(config,lev+1,off,"Decoding of RLE16 failed"); 822 psiconv_error(config,lev+1,off,"Decoding of RLE16 failed");
804 if (!res) 823 if (!res)
805 return -PSICONV_E_NOMEM; 824 return -PSICONV_E_NOMEM;
806 else 825 else
807 return res; 826 return res;
808} 827}
868 return 0; 887 return 0;
869 888
870ERROR2: 889ERROR2:
871 psiconv_list_free(*decoded); 890 psiconv_list_free(*decoded);
872ERROR1: 891ERROR1:
873 psiconv_warn(config,lev+1,off,"Decoding of RLE24 failed"); 892 psiconv_error(config,lev+1,off,"Decoding of RLE24 failed");
874 if (!res) 893 if (!res)
875 return -PSICONV_E_NOMEM; 894 return -PSICONV_E_NOMEM;
876 else 895 else
877 return res; 896 return res;
878} 897}
899 while (nr % 4) 918 while (nr % 4)
900 nr ++; 919 nr ++;
901 input = 0; 920 input = 0;
902 ibits = 0; 921 ibits = 0;
903 for (x= 0; x < xsize; x++) { 922 for (x= 0; x < xsize; x++) {
923#ifdef LOUD
904 psiconv_progress(config,lev+2,off, 924 psiconv_progress(config,lev+2,off,
905 "Processing pixel at (x,y) = (%04x,%04x)",x,y); 925 "Processing pixel at (x,y) = (%04x,%04x)",x,y);
926#endif
906 output = 0; 927 output = 0;
907 obits = 0; 928 obits = 0;
908 while (obits < colordepth) { 929 while (obits < colordepth) {
909 if (ibits == 0) { 930 if (ibits == 0) {
931#ifdef LOUD
910 psiconv_progress(config,lev+3,off, 932 psiconv_progress(config,lev+3,off,
911 "Going to read byte %08x",nr); 933 "Going to read byte %08x",nr);
934#endif
912 if (!(ientry = psiconv_list_get(bytes,nr))) 935 if (!(ientry = psiconv_list_get(bytes,nr)))
913 goto ERROR2; 936 goto ERROR2;
937#ifdef LOUD
914 psiconv_debug(config,lev+3,off,"Byte value: %02x",*ientry); 938 psiconv_debug(config,lev+3,off,"Byte value: %02x",*ientry);
939#endif
915 input = *ientry; 940 input = *ientry;
916 ibits = 8; 941 ibits = 8;
917 nr ++; 942 nr ++;
918 } 943 }
919 bits = ibits + obits > colordepth?colordepth-obits:ibits; 944 bits = ibits + obits > colordepth?colordepth-obits:ibits;
921 output |= input & ((1 << bits) - 1); 946 output |= input & ((1 << bits) - 1);
922 input = input >> bits; 947 input = input >> bits;
923 ibits -= bits; 948 ibits -= bits;
924 obits += bits; 949 obits += bits;
925 } 950 }
951#ifdef LOUD
926 psiconv_debug(config,lev+2,off,"Pixel value: %08x",output); 952 psiconv_debug(config,lev+2,off,"Pixel value: %08x",output);
953#endif
927 if ((res = psiconv_list_add(*pixels,&output))) 954 if ((res = psiconv_list_add(*pixels,&output)))
928 goto ERROR2; 955 goto ERROR2;
929 } 956 }
930 } 957 }
931 958
935 962
936 963
937ERROR2: 964ERROR2:
938 psiconv_list_free(*pixels); 965 psiconv_list_free(*pixels);
939ERROR1: 966ERROR1:
940 psiconv_warn(config,lev+1,off,"Converting bytes to pixels failed"); 967 psiconv_error(config,lev+1,off,"Converting bytes to pixels failed");
941 if (!res) 968 if (!res)
942 return -PSICONV_E_NOMEM; 969 return -PSICONV_E_NOMEM;
943 else 970 else
944 return res; 971 return res;
945} 972}
969 (*floats).length = psiconv_list_length(pixels); 996 (*floats).length = psiconv_list_length(pixels);
970 997
971 for (i = 0; i < psiconv_list_length(pixels); i++) { 998 for (i = 0; i < psiconv_list_length(pixels); i++) {
972 if (!(pixel = psiconv_list_get(pixels,i))) 999 if (!(pixel = psiconv_list_get(pixels,i)))
973 goto ERROR4; 1000 goto ERROR4;
1001#ifdef LOUD
974 psiconv_progress(config,lev+2,off, "Handling pixel %04x (%04x)",i,*pixel); 1002 psiconv_progress(config,lev+2,off, "Handling pixel %04x (%04x)",i,*pixel);
1003#endif
975 if (!palet.length) { 1004 if (!palet.length) {
976 if (color) { 1005 if (color) {
977 (*floats).blue[i] = ((float) (*pixel & ((1 << bluebits) - 1))) / 1006 (*floats).blue[i] = ((float) (*pixel & ((1 << bluebits) - 1))) /
978 (1 << bluebits); 1007 (1 << bluebits);
979 (*floats).green[i] = ((float) ((*pixel >> bluebits) & 1008 (*floats).green[i] = ((float) ((*pixel >> bluebits) &
996 (*floats).red[i] = palet.red[*pixel]; 1025 (*floats).red[i] = palet.red[*pixel];
997 (*floats).green[i] = palet.green[*pixel]; 1026 (*floats).green[i] = palet.green[*pixel];
998 (*floats).blue[i] = palet.blue[*pixel]; 1027 (*floats).blue[i] = palet.blue[*pixel];
999 } 1028 }
1000 } 1029 }
1030#ifdef LOUD
1001 psiconv_debug(config,lev+2,off, "Pixel: Red (%f), green (%f), blue (%f)", 1031 psiconv_debug(config,lev+2,off, "Pixel: Red (%f), green (%f), blue (%f)",
1002 (*floats).red[i],(*floats).green[i],(*floats).blue[i]); 1032 (*floats).red[i],(*floats).green[i],(*floats).blue[i]);
1033#endif
1003 } 1034 }
1004 psiconv_progress(config,lev+1,off,"Finished converting pixels to floats"); 1035 psiconv_progress(config,lev+1,off,"Finished converting pixels to floats");
1005 return 0; 1036 return 0;
1006 1037
1007ERROR4: 1038ERROR4:
1009ERROR3: 1040ERROR3:
1010 free((*floats).green); 1041 free((*floats).green);
1011ERROR2: 1042ERROR2:
1012 free((*floats).red); 1043 free((*floats).red);
1013ERROR1: 1044ERROR1:
1014 psiconv_warn(config,lev+1,off,"Converting pixels to floats failed"); 1045 psiconv_error(config,lev+1,off,"Converting pixels to floats failed");
1015 if (!res) 1046 if (!res)
1016 return -PSICONV_E_NOMEM; 1047 return -PSICONV_E_NOMEM;
1017 else 1048 else
1018 return res; 1049 return res;
1019} 1050}

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

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