… | |
… | |
22 | #include <stdlib.h> |
22 | #include <stdlib.h> |
23 | #include <string.h> |
23 | #include <string.h> |
24 | |
24 | |
25 | #include "parse_routines.h" |
25 | #include "parse_routines.h" |
26 | #include "error.h" |
26 | #include "error.h" |
|
|
27 | |
|
|
28 | #ifdef DMALLOC |
|
|
29 | #include <dmalloc.h> |
|
|
30 | #endif |
|
|
31 | |
27 | |
32 | |
28 | static int psiconv_parse_layout_section(const psiconv_buffer buf, |
33 | static int psiconv_parse_layout_section(const psiconv_buffer buf, |
29 | int lev,psiconv_u32 off, |
34 | int lev,psiconv_u32 off, |
30 | int *length, |
35 | int *length, |
31 | psiconv_text_and_layout result, |
36 | psiconv_text_and_layout result, |
… | |
… | |
87 | (*result)->file = psiconv_texted_file; |
92 | (*result)->file = psiconv_texted_file; |
88 | psiconv_debug(lev+2,off+len,"File is a TextEd file"); |
93 | psiconv_debug(lev+2,off+len,"File is a TextEd file"); |
89 | } else if ((*result)->uid3 == PSICONV_ID_SKETCH) { |
94 | } else if ((*result)->uid3 == PSICONV_ID_SKETCH) { |
90 | (*result)->file = psiconv_sketch_file; |
95 | (*result)->file = psiconv_sketch_file; |
91 | psiconv_debug(lev+2,off+len,"File is a Sketch file"); |
96 | psiconv_debug(lev+2,off+len,"File is a Sketch file"); |
|
|
97 | } else if ((*result)->uid3 == PSICONV_ID_SHEET) { |
|
|
98 | (*result)->file = psiconv_sheet_file; |
|
|
99 | psiconv_debug(lev+2,off+len,"File is a Sheet file"); |
92 | } |
100 | } |
93 | } else if ((*result)->uid2 == PSICONV_ID_MBM_FILE) { |
101 | } else if ((*result)->uid2 == PSICONV_ID_MBM_FILE) { |
94 | (*result)->file = psiconv_mbm_file; |
102 | (*result)->file = psiconv_mbm_file; |
95 | if ((*result)->uid3 != 0x00) |
103 | if ((*result)->uid3 != 0x00) |
96 | psiconv_warn(lev+2,off+len,"UID3 set in MBM file?!?"); |
104 | psiconv_warn(lev+2,off+len,"UID3 set in MBM file?!?"); |
97 | psiconv_debug(lev+2,off+len,"File is a MBM file"); |
105 | psiconv_debug(lev+2,off+len,"File is a MBM file"); |
… | |
… | |
706 | psiconv_warn(lev+3,off+len, |
714 | psiconv_warn(lev+3,off+len, |
707 | "Layout section inlines: not enough element"); |
715 | "Layout section inlines: not enough element"); |
708 | psiconv_debug(lev+3,off+len,"Can't read element!"); |
716 | psiconv_debug(lev+3,off+len,"Can't read element!"); |
709 | } else { |
717 | } else { |
710 | total ++; |
718 | total ++; |
|
|
719 | in_line.object = NULL; |
|
|
720 | in_line.layout = NULL; |
711 | if (!(in_line.layout = psiconv_clone_character_layout |
721 | if (!(in_line.layout = psiconv_clone_character_layout |
712 | (para->base_character))) |
722 | (para->base_character))) |
713 | goto ERROR4; |
723 | goto ERROR4; |
714 | psiconv_progress(lev+4,off+len,"Going to read the element type"); |
724 | psiconv_progress(lev+4,off+len,"Going to read the element type"); |
715 | temp = psiconv_read_u8(buf,lev+4,len+off,&res); |
725 | temp = psiconv_read_u8(buf,lev+4,len+off,&res); |
716 | if (res) |
726 | if (res) |
717 | goto ERROR4; |
727 | goto ERROR5; |
718 | len += 1; |
728 | len += 1; |
719 | psiconv_debug(lev+4,off+len,"Type: %02x",temp); |
729 | psiconv_debug(lev+4,off+len,"Type: %02x",temp); |
720 | psiconv_progress(lev+4,off+len, |
730 | psiconv_progress(lev+4,off+len, |
721 | "Going to read the number of characters it applies to"); |
731 | "Going to read the number of characters it applies to"); |
722 | in_line.length = psiconv_read_u32(buf,lev+4,len+off,&res); |
732 | in_line.length = psiconv_read_u32(buf,lev+4,len+off,&res); |
723 | if (res) |
733 | if (res) |
724 | goto ERROR4; |
734 | goto ERROR5; |
725 | psiconv_debug(lev+4,off+len,"Length: %02x",in_line.length); |
735 | psiconv_debug(lev+4,off+len,"Length: %02x",in_line.length); |
726 | len += 4; |
736 | len += 4; |
727 | psiconv_progress(lev+4,off+len,"Going to read the character layout"); |
737 | psiconv_progress(lev+4,off+len,"Going to read the character layout"); |
728 | if ((res = psiconv_parse_character_layout_list(buf,lev+4,off+len,&leng, |
738 | if ((res = psiconv_parse_character_layout_list(buf,lev+4,off+len,&leng, |
729 | in_line.layout))) |
739 | in_line.layout))) |
730 | goto ERROR4; |
740 | goto ERROR5; |
731 | len += leng; |
741 | len += leng; |
732 | |
742 | |
733 | if (temp == 0x01) { |
743 | if (temp == 0x01) { |
734 | psiconv_debug(lev+4,off+len,"Skipping object data"); |
744 | psiconv_debug(lev+4,off+len,"Found an embedded object"); |
735 | len += 0x10; |
745 | psiconv_progress(lev+4,off+len,"Going to read the object marker " |
|
|
746 | "(0x%08x expected)",PSICONV_ID_OBJECT); |
|
|
747 | temp = psiconv_read_u32(buf,lev+4,off+len,&res); |
|
|
748 | if (res) |
|
|
749 | goto ERROR5; |
|
|
750 | if (temp != PSICONV_ID_OBJECT) { |
|
|
751 | psiconv_warn(lev+4,off+len,"Unknown id marks embedded object"); |
|
|
752 | psiconv_debug(lev+4,off+len,"Marker: read %08x, expected %08x", |
|
|
753 | temp,PSICONV_ID_OBJECT); |
|
|
754 | } |
|
|
755 | len += 4; |
|
|
756 | psiconv_progress(lev+4,off+len, |
|
|
757 | "Going to read the Embedded Object Section offset"); |
|
|
758 | temp = psiconv_read_u32(buf,lev+4,off+len,&res); |
|
|
759 | if (res) |
|
|
760 | goto ERROR5; |
|
|
761 | psiconv_debug(lev+4,off+len, "Offset: %08x",temp); |
|
|
762 | len += 4; |
|
|
763 | psiconv_progress(lev+4,off+len, |
|
|
764 | "Going to parse the Embedded Object"); |
|
|
765 | if ((res = psiconv_parse_embedded_object(buf,lev+4,temp, |
|
|
766 | NULL,&(in_line.object)))) |
|
|
767 | goto ERROR5; |
|
|
768 | psiconv_progress(lev+4,off+len, |
|
|
769 | "Going to read the object width"); |
|
|
770 | in_line.object_width = psiconv_read_length(buf,lev+4,off+len, |
|
|
771 | &leng,&res); |
|
|
772 | if (res) |
|
|
773 | goto ERROR5; |
|
|
774 | psiconv_debug(lev+4,off+len,"Object width: %f cm", |
|
|
775 | in_line.object_width); |
|
|
776 | len += leng; |
|
|
777 | psiconv_progress(lev+4,off+len, |
|
|
778 | "Going to read the object height"); |
|
|
779 | in_line.object_height = psiconv_read_length(buf,lev+4,off+len,&leng, |
|
|
780 | &res); |
|
|
781 | if (res) |
|
|
782 | goto ERROR5; |
|
|
783 | psiconv_debug(lev+4,off+len,"Object height: %f cm", |
|
|
784 | in_line.object_height); |
|
|
785 | len += leng; |
736 | } else if (temp != 0x00) { |
786 | } else if (temp != 0x00) { |
737 | psiconv_warn(lev+4,off+len,"Layout section unknown inline type"); |
787 | psiconv_warn(lev+4,off+len,"Layout section unknown inline type"); |
738 | } |
788 | } |
739 | if (line_length + in_line.length > strlen(para->text)) { |
789 | if (line_length + in_line.length > strlen(para->text)) { |
740 | psiconv_warn(lev+4,off+len, |
790 | psiconv_warn(lev+4,off+len, |
… | |
… | |
742 | res = -1; |
792 | res = -1; |
743 | in_line.length = strlen(para->text) - line_length; |
793 | in_line.length = strlen(para->text) - line_length; |
744 | } |
794 | } |
745 | line_length += in_line.length; |
795 | line_length += in_line.length; |
746 | if ((res = psiconv_list_add(para->in_lines,&in_line))) |
796 | if ((res = psiconv_list_add(para->in_lines,&in_line))) |
747 | goto ERROR4; |
797 | goto ERROR5; |
748 | } |
798 | } |
749 | } |
799 | } |
750 | } |
800 | } |
751 | |
801 | |
752 | if (total != nr) { |
802 | if (total != nr) { |
… | |
… | |
788 | psiconv_free_character_layout(anon.character); |
838 | psiconv_free_character_layout(anon.character); |
789 | ERROR3_1: |
839 | ERROR3_1: |
790 | psiconv_free_paragraph_layout(anon.paragraph); |
840 | psiconv_free_paragraph_layout(anon.paragraph); |
791 | goto ERROR3; |
841 | goto ERROR3; |
792 | |
842 | |
|
|
843 | ERROR5: |
|
|
844 | if (in_line.layout) |
|
|
845 | psiconv_free_character_layout(in_line.layout); |
|
|
846 | if (in_line.object) |
|
|
847 | psiconv_free_object(in_line.object); |
793 | ERROR4: |
848 | ERROR4: |
794 | free(inline_count); |
849 | free(inline_count); |
795 | ERROR3: |
850 | ERROR3: |
796 | for (i = 0; i < psiconv_list_length(anon_styles); i++) { |
851 | for (i = 0; i < psiconv_list_length(anon_styles); i++) { |
797 | if (!(anon_ptr = psiconv_list_get(anon_styles,i))) { |
852 | if (!(anon_ptr = psiconv_list_get(anon_styles,i))) { |
… | |
… | |
822 | { |
877 | { |
823 | return psiconv_parse_layout_section(buf,lev,off,length,result,styles,1); |
878 | return psiconv_parse_layout_section(buf,lev,off,length,result,styles,1); |
824 | } |
879 | } |
825 | |
880 | |
826 | int psiconv_parse_styleless_layout_section(const psiconv_buffer buf, |
881 | int psiconv_parse_styleless_layout_section(const psiconv_buffer buf, |
827 | int lev,psiconv_u32 off, |
882 | int lev,psiconv_u32 off, |
828 | int *length, |
883 | int *length, |
829 | psiconv_text_and_layout result, |
884 | psiconv_text_and_layout result, |
830 | psiconv_character_layout base_char, |
885 | const psiconv_character_layout base_char, |
831 | psiconv_paragraph_layout base_para) |
886 | const psiconv_paragraph_layout base_para) |
832 | { |
887 | { |
833 | int res = 0; |
888 | int res = 0; |
834 | psiconv_word_styles_section styles_section; |
889 | psiconv_word_styles_section styles_section; |
835 | |
890 | |
836 | if (!(styles_section = malloc(sizeof(*styles_section)))) |
891 | if (!(styles_section = malloc(sizeof(*styles_section)))) |
… | |
… | |
874 | return -PSICONV_E_NOMEM; |
929 | return -PSICONV_E_NOMEM; |
875 | else |
930 | else |
876 | return res; |
931 | return res; |
877 | } |
932 | } |
878 | |
933 | |
|
|
934 | int psiconv_parse_embedded_object(const psiconv_buffer buf, int lev, |
|
|
935 | psiconv_u32 off, int *length, |
|
|
936 | psiconv_object *result) |
|
|
937 | { |
|
|
938 | int res=0; |
|
|
939 | int len=0; |
|
|
940 | int leng,i; |
|
|
941 | psiconv_section_table_section table; |
|
|
942 | psiconv_section_table_entry entry; |
|
|
943 | psiconv_u32 icon_sec=0,display_sec=0,table_sec=0; |
|
|
944 | |
|
|
945 | psiconv_progress(lev+1,off+len,"Going to read an Embedded Object"); |
|
|
946 | if (!(*result = malloc(sizeof(**result)))) |
|
|
947 | goto ERROR1; |
|
|
948 | |
|
|
949 | psiconv_progress(lev+2,off+len,"Going to read the Embedded Object Section"); |
|
|
950 | psiconv_parse_section_table_section(buf,lev+2,off+len,&leng,&table); |
|
|
951 | len += leng; |
|
|
952 | |
|
|
953 | for (i = 0; i < psiconv_list_length(table); i++) { |
|
|
954 | psiconv_progress(lev+2,off+len,"Going to read entry %d",i); |
|
|
955 | if (!(entry = psiconv_list_get(table,i))) |
|
|
956 | goto ERROR2; |
|
|
957 | if (entry->id == PSICONV_ID_OBJECT_DISPLAY_SECTION) { |
|
|
958 | display_sec = entry->offset; |
|
|
959 | psiconv_debug(lev+3,off+len,"Found the Object Display Section at %08x", |
|
|
960 | display_sec); |
|
|
961 | } else if (entry->id == PSICONV_ID_OBJECT_ICON_SECTION) { |
|
|
962 | icon_sec = entry->offset; |
|
|
963 | psiconv_debug(lev+3,off+len,"Found the Object Icon Section at %08x", |
|
|
964 | icon_sec); |
|
|
965 | } else if (entry->id == PSICONV_ID_OBJECT_SECTION_TABLE_SECTION) { |
|
|
966 | table_sec = entry->offset; |
|
|
967 | psiconv_debug(lev+3,off+len,"Found the Object Section Table Section at %08x", |
|
|
968 | table_sec); |
|
|
969 | } else { |
|
|
970 | psiconv_warn(lev+3,off+len, |
|
|
971 | "Found unknown section in the Object Display Section " |
|
|
972 | "(ignoring)"); |
|
|
973 | psiconv_debug(lev+3,off+len,"Section ID %08x, offset %08x", |
|
|
974 | entry->id, entry->offset); |
|
|
975 | } |
|
|
976 | } |
|
|
977 | |
|
|
978 | psiconv_progress(lev+2,off+len,"Looking for the Object Display Section"); |
|
|
979 | if (!icon_sec) { |
|
|
980 | psiconv_warn(lev+2,off+len,"Object Display Section not found"); |
|
|
981 | (*result)->display = NULL; |
|
|
982 | } else { |
|
|
983 | psiconv_debug(lev+2,off+len,"Object Display Section at offset %08x", |
|
|
984 | display_sec); |
|
|
985 | if ((res = psiconv_parse_object_display_section(buf,lev+2,display_sec,NULL, |
|
|
986 | &(*result)->display))) |
|
|
987 | goto ERROR2; |
|
|
988 | } |
|
|
989 | |
|
|
990 | psiconv_progress(lev+2,off+len,"Looking for the Object Icon Section"); |
|
|
991 | if (!icon_sec) { |
|
|
992 | psiconv_warn(lev+2,off+len,"Object Icon Section not found"); |
|
|
993 | (*result)->icon = NULL; |
|
|
994 | } else { |
|
|
995 | psiconv_debug(lev+2,off+len,"Object Icon Section at offset %08x",icon_sec); |
|
|
996 | if ((res = psiconv_parse_object_icon_section(buf,lev+2,icon_sec,NULL, |
|
|
997 | &(*result)->icon))) |
|
|
998 | goto ERROR2; |
|
|
999 | } |
|
|
1000 | |
|
|
1001 | if (length) |
|
|
1002 | *length = len; |
|
|
1003 | |
|
|
1004 | psiconv_progress(lev+1,off+len-1,"End of Embedded Object Section " |
|
|
1005 | "(total length: %08x)",len); |
|
|
1006 | |
|
|
1007 | return res; |
|
|
1008 | |
|
|
1009 | |
|
|
1010 | ERROR2: |
|
|
1011 | psiconv_free_section_table_section(table); |
|
|
1012 | ERROR1: |
|
|
1013 | psiconv_warn(lev+1,off,"Reading Embedded Object failed"); |
|
|
1014 | |
|
|
1015 | if (length) |
|
|
1016 | *length = 0; |
|
|
1017 | |
|
|
1018 | if (res == 0) |
|
|
1019 | return -PSICONV_E_NOMEM; |
|
|
1020 | else |
|
|
1021 | return res; |
|
|
1022 | } |
|
|
1023 | |
|
|
1024 | int psiconv_parse_object_display_section(const psiconv_buffer buf,int lev, |
|
|
1025 | psiconv_u32 off, int *length, |
|
|
1026 | psiconv_object_display_section *result) |
|
|
1027 | { |
|
|
1028 | int res = 0; |
|
|
1029 | int len = 0; |
|
|
1030 | int leng; |
|
|
1031 | psiconv_u32 temp; |
|
|
1032 | |
|
|
1033 | psiconv_progress(lev+1,off,"Going to read the Object Display Section"); |
|
|
1034 | if (!(*result = malloc(sizeof(**result)))) |
|
|
1035 | goto ERROR1; |
|
|
1036 | |
|
|
1037 | psiconv_progress(lev+2,off+len,"Going to read the display as icon flag " |
|
|
1038 | "(expecting 0x00 or 0x01)"); |
|
|
1039 | temp = psiconv_read_u8(buf,lev+2,off+len,&res); |
|
|
1040 | if (res) |
|
|
1041 | goto ERROR2; |
|
|
1042 | if (temp == 0x00) { |
|
|
1043 | (*result)->show_icon = psiconv_bool_true; |
|
|
1044 | psiconv_debug(lev+2,off+len,"Displayed as full document"); |
|
|
1045 | } else if (temp == 0x01) { |
|
|
1046 | (*result)->show_icon = psiconv_bool_false; |
|
|
1047 | psiconv_debug(lev+2,off+len,"Displayed as icon"); |
|
|
1048 | } else { |
|
|
1049 | psiconv_warn(lev+2,off+len,"Unknown Object Display Section Icon Flag"); |
|
|
1050 | psiconv_debug(lev+2,off+len,"Icon flag found: %02x",temp); |
|
|
1051 | /* Improvise */ |
|
|
1052 | (*result)->show_icon = (temp & 0x01?psiconv_bool_false:psiconv_bool_true); |
|
|
1053 | } |
|
|
1054 | len ++; |
|
|
1055 | |
|
|
1056 | psiconv_progress(lev+2,off+len,"Going to read the icon width"); |
|
|
1057 | (*result)->width = psiconv_read_length(buf,lev+2,off+len,&leng,&res); |
|
|
1058 | if (res) |
|
|
1059 | goto ERROR2; |
|
|
1060 | psiconv_debug(lev+2,off+len,"Icon width: %f cm",(*result)->width); |
|
|
1061 | len += leng; |
|
|
1062 | |
|
|
1063 | psiconv_progress(lev+2,off+len,"Going to read the icon height"); |
|
|
1064 | (*result)->height = psiconv_read_length(buf,lev+2,off+len,&leng,&res); |
|
|
1065 | if (res) |
|
|
1066 | goto ERROR2; |
|
|
1067 | psiconv_debug(lev+2,off+len,"Icon length: %f cm",(*result)->height); |
|
|
1068 | len += leng; |
|
|
1069 | |
|
|
1070 | psiconv_progress(lev+2,off+len,"Going to read unknown long (%08x expected)", |
|
|
1071 | 0); |
|
|
1072 | temp = psiconv_read_u32(buf,lev+2,off+len,&res); |
|
|
1073 | if (temp != 0) { |
|
|
1074 | psiconv_warn(lev+2,off+len,"Unknown Object Display Section final long"); |
|
|
1075 | psiconv_debug(lev+2,off+len,"Long read: %08x",temp); |
|
|
1076 | } |
|
|
1077 | len += 4; |
|
|
1078 | |
|
|
1079 | if (length) |
|
|
1080 | *length = len; |
|
|
1081 | |
|
|
1082 | psiconv_progress(lev+1,off+len-1,"End of Object Display Section" |
|
|
1083 | "(total length: %08x",len); |
|
|
1084 | return res; |
|
|
1085 | |
|
|
1086 | ERROR2: |
|
|
1087 | free(*result); |
|
|
1088 | ERROR1: |
|
|
1089 | psiconv_warn(lev+1,off+len,"Reading of Object Display Section failed"); |
|
|
1090 | if (length) |
|
|
1091 | *length=0; |
|
|
1092 | if (!res) |
|
|
1093 | return -PSICONV_E_NOMEM; |
|
|
1094 | else |
|
|
1095 | return res; |
|
|
1096 | } |
|
|
1097 | |
|
|
1098 | int psiconv_parse_object_icon_section(const psiconv_buffer buf,int lev, |
|
|
1099 | psiconv_u32 off, int *length, |
|
|
1100 | psiconv_object_icon_section *result) |
|
|
1101 | { |
|
|
1102 | int res = 0; |
|
|
1103 | int len = 0; |
|
|
1104 | int leng; |
|
|
1105 | |
|
|
1106 | psiconv_progress(lev+1,off,"Going to read the Object Icon Section"); |
|
|
1107 | if (!(*result = malloc(sizeof(**result)))) |
|
|
1108 | goto ERROR1; |
|
|
1109 | |
|
|
1110 | psiconv_progress(lev+2,off+len,"Going to read the icon name"); |
|
|
1111 | (*result)->icon_name = psiconv_read_string(buf,lev+2,off+len,&leng,&res); |
|
|
1112 | if (res) |
|
|
1113 | goto ERROR2; |
|
|
1114 | psiconv_debug(lev+2,off+len,"Icon name: %s",(*result)->icon_name); |
|
|
1115 | len += leng; |
|
|
1116 | |
|
|
1117 | psiconv_progress(lev+2,off+len,"Going to read the icon width"); |
|
|
1118 | (*result)->icon_width = psiconv_read_length(buf,lev+2,off+len,&leng,&res); |
|
|
1119 | if (res) |
|
|
1120 | goto ERROR3; |
|
|
1121 | psiconv_debug(lev+2,off+len,"Icon width: %f cm",(*result)->icon_width); |
|
|
1122 | len += leng; |
|
|
1123 | |
|
|
1124 | psiconv_progress(lev+2,off+len,"Going to read the icon height"); |
|
|
1125 | (*result)->icon_height = psiconv_read_length(buf,lev+2,off+len,&leng,&res); |
|
|
1126 | if (res) |
|
|
1127 | goto ERROR3; |
|
|
1128 | psiconv_debug(lev+2,off+len,"Icon length: %f cm",(*result)->icon_height); |
|
|
1129 | len += leng; |
|
|
1130 | |
|
|
1131 | if (length) |
|
|
1132 | *length = len; |
|
|
1133 | |
|
|
1134 | psiconv_progress(lev+1,off+len-1,"End of Object Icon Section" |
|
|
1135 | "(total length: %08x",len); |
|
|
1136 | return res; |
|
|
1137 | |
|
|
1138 | ERROR3: |
|
|
1139 | free((*result)->icon_name); |
|
|
1140 | ERROR2: |
|
|
1141 | free(*result); |
|
|
1142 | ERROR1: |
|
|
1143 | psiconv_warn(lev+1,off+len,"Reading of Object Icon Section failed"); |
|
|
1144 | if (length) |
|
|
1145 | *length=0; |
|
|
1146 | if (!res) |
|
|
1147 | return -PSICONV_E_NOMEM; |
|
|
1148 | else |
|
|
1149 | return res; |
|
|
1150 | } |