--- psiconv/trunk/lib/psiconv/parse_common.c 2000/12/15 01:16:43 65 +++ psiconv/trunk/lib/psiconv/parse_common.c 2003/11/21 15:39:14 162 @@ -22,8 +22,13 @@ #include #include -#include "data.h" #include "parse_routines.h" +#include "error.h" + +#ifdef DMALLOC +#include +#endif + static int psiconv_parse_layout_section(const psiconv_buffer buf, int lev,psiconv_u32 off, @@ -31,6 +36,9 @@ psiconv_text_and_layout result, psiconv_word_styles_section styles, int with_styles); +static psiconv_file_type_t psiconv_determine_embedded_object_type + (const psiconv_buffer buf,int lev, + int *status); int psiconv_parse_header_section(const psiconv_buffer buf,int lev, psiconv_u32 off, int *length, @@ -89,7 +97,10 @@ } else if ((*result)->uid3 == PSICONV_ID_SKETCH) { (*result)->file = psiconv_sketch_file; psiconv_debug(lev+2,off+len,"File is a Sketch file"); - } + } else if ((*result)->uid3 == PSICONV_ID_SHEET) { + (*result)->file = psiconv_sheet_file; + psiconv_debug(lev+2,off+len,"File is a Sheet file"); + } } else if ((*result)->uid2 == PSICONV_ID_MBM_FILE) { (*result)->file = psiconv_mbm_file; if ((*result)->uid3 != 0x00) @@ -708,31 +719,73 @@ psiconv_debug(lev+3,off+len,"Can't read element!"); } else { total ++; + in_line.object = NULL; + in_line.layout = NULL; if (!(in_line.layout = psiconv_clone_character_layout (para->base_character))) goto ERROR4; psiconv_progress(lev+4,off+len,"Going to read the element type"); temp = psiconv_read_u8(buf,lev+4,len+off,&res); if (res) - goto ERROR4; + goto ERROR5; len += 1; - psiconv_debug(lev+4,off,"Type: %02x",temp); - psiconv_progress(lev+4,off, + psiconv_debug(lev+4,off+len,"Type: %02x",temp); + psiconv_progress(lev+4,off+len, "Going to read the number of characters it applies to"); in_line.length = psiconv_read_u32(buf,lev+4,len+off,&res); if (res) - goto ERROR4; + goto ERROR5; psiconv_debug(lev+4,off+len,"Length: %02x",in_line.length); len += 4; psiconv_progress(lev+4,off+len,"Going to read the character layout"); if ((res = psiconv_parse_character_layout_list(buf,lev+4,off+len,&leng, in_line.layout))) - goto ERROR4; + goto ERROR5; len += leng; if (temp == 0x01) { - psiconv_debug(lev+4,off+len,"Skipping object data"); - len += 0x10; + psiconv_debug(lev+4,off+len,"Found an embedded object"); + psiconv_progress(lev+4,off+len,"Going to read the object marker " + "(0x%08x expected)",PSICONV_ID_OBJECT); + temp = psiconv_read_u32(buf,lev+4,off+len,&res); + if (res) + goto ERROR5; + if (temp != PSICONV_ID_OBJECT) { + psiconv_warn(lev+4,off+len,"Unknown id marks embedded object"); + psiconv_debug(lev+4,off+len,"Marker: read %08x, expected %08x", + temp,PSICONV_ID_OBJECT); + } + len += 4; + psiconv_progress(lev+4,off+len, + "Going to read the Embedded Object Section offset"); + temp = psiconv_read_u32(buf,lev+4,off+len,&res); + if (res) + goto ERROR5; + psiconv_debug(lev+4,off+len, "Offset: %08x",temp); + len += 4; + psiconv_progress(lev+4,off+len, + "Going to parse the Embedded Object"); + if ((res = psiconv_parse_embedded_object(buf,lev+4,temp, + NULL,&(in_line.object)))) + goto ERROR5; + psiconv_progress(lev+4,off+len, + "Going to read the object width"); + in_line.object_width = psiconv_read_length(buf,lev+4,off+len, + &leng,&res); + if (res) + goto ERROR5; + psiconv_debug(lev+4,off+len,"Object width: %f cm", + in_line.object_width); + len += leng; + psiconv_progress(lev+4,off+len, + "Going to read the object height"); + in_line.object_height = psiconv_read_length(buf,lev+4,off+len,&leng, + &res); + if (res) + goto ERROR5; + psiconv_debug(lev+4,off+len,"Object height: %f cm", + in_line.object_height); + len += leng; } else if (temp != 0x00) { psiconv_warn(lev+4,off+len,"Layout section unknown inline type"); } @@ -744,7 +797,7 @@ } line_length += in_line.length; if ((res = psiconv_list_add(para->in_lines,&in_line))) - goto ERROR4; + goto ERROR5; } } } @@ -769,7 +822,7 @@ if (length) *length = len; - psiconv_progress(lev+1,off+len-1,"End of layout section (total length: %08x", + psiconv_progress(lev+1,off+len-1,"End of layout section (total length: %08x)", len); return 0; @@ -790,6 +843,11 @@ psiconv_free_paragraph_layout(anon.paragraph); goto ERROR3; +ERROR5: + if (in_line.layout) + psiconv_free_character_layout(in_line.layout); + if (in_line.object) + psiconv_free_object(in_line.object); ERROR4: free(inline_count); ERROR3: @@ -824,11 +882,11 @@ } int psiconv_parse_styleless_layout_section(const psiconv_buffer buf, - int lev,psiconv_u32 off, - int *length, - psiconv_text_and_layout result, - psiconv_character_layout base_char, - psiconv_paragraph_layout base_para) + int lev,psiconv_u32 off, + int *length, + psiconv_text_and_layout result, + const psiconv_character_layout base_char, + const psiconv_paragraph_layout base_para) { int res = 0; psiconv_word_styles_section styles_section; @@ -876,3 +934,352 @@ return res; } +int psiconv_parse_embedded_object(const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + psiconv_object *result) +{ + int res=0; + int len=0; + int leng,i; + psiconv_section_table_section table; + psiconv_section_table_entry entry; + psiconv_u32 icon_sec=0,display_sec=0,table_sec=0; + psiconv_buffer subbuf; + + psiconv_progress(lev+1,off+len,"Going to read an Embedded Object"); + if (!(*result = malloc(sizeof(**result)))) + goto ERROR1; + + psiconv_progress(lev+2,off+len,"Going to read the Embedded Object Section"); + psiconv_parse_section_table_section(buf,lev+2,off+len,&leng,&table); + len += leng; + + for (i = 0; i < psiconv_list_length(table); i++) { + psiconv_progress(lev+2,off+len,"Going to read entry %d",i); + if (!(entry = psiconv_list_get(table,i))) + goto ERROR2; + if (entry->id == PSICONV_ID_OBJECT_DISPLAY_SECTION) { + display_sec = entry->offset; + psiconv_debug(lev+3,off+len,"Found the Object Display Section at %08x", + display_sec); + } else if (entry->id == PSICONV_ID_OBJECT_ICON_SECTION) { + icon_sec = entry->offset; + psiconv_debug(lev+3,off+len,"Found the Object Icon Section at %08x", + icon_sec); + } else if (entry->id == PSICONV_ID_OBJECT_SECTION_TABLE_SECTION) { + table_sec = entry->offset; + psiconv_debug(lev+3,off+len,"Found the Object Section Table Section at %08x", + table_sec); + } else { + psiconv_warn(lev+3,off+len, + "Found unknown section in the Object Display Section " + "(ignoring)"); + psiconv_debug(lev+3,off+len,"Section ID %08x, offset %08x", + entry->id, entry->offset); + } + } + + psiconv_progress(lev+2,off+len,"Looking for the Object Display Section"); + if (!icon_sec) { + psiconv_warn(lev+2,off+len,"Object Display Section not found"); + (*result)->display = NULL; + } else { + psiconv_debug(lev+2,off+len,"Object Display Section at offset %08x", + display_sec); + if ((res = psiconv_parse_object_display_section(buf,lev+2,display_sec,NULL, + &(*result)->display))) + goto ERROR2; + } + + psiconv_progress(lev+2,off+len,"Looking for the Object Icon Section"); + if (!icon_sec) { + psiconv_warn(lev+2,off+len,"Object Icon Section not found"); + (*result)->icon = NULL; + } else { + psiconv_debug(lev+2,off+len,"Object Icon Section at offset %08x",icon_sec); + if ((res = psiconv_parse_object_icon_section(buf,lev+2,icon_sec,NULL, + &(*result)->icon))) + goto ERROR3; + } + + psiconv_progress(lev+2,off+len, + "Looking for the Section Table Offset Section"); + if (!table_sec) { + psiconv_warn(lev+2,off+len, + "Embedded Section Table Offset Section not found"); + (*result)->object = NULL; + } else { + psiconv_progress(lev+2,off+len, + "Extracting object: add %08x to all following offsets", + table_sec); + /* We can't determine the length of the object, so we just take it all */ + if ((res = psiconv_buffer_subbuffer(&subbuf,buf,table_sec, + psiconv_buffer_length(buf)-table_sec))) + goto ERROR4; + + if (!((*result)->object = malloc(sizeof(*(*result)->object)))) + goto ERROR5; + + /* We need to find the file type, but we don't have a normal header */ + /* So we try to find the Application ID Section and hope for the best */ + psiconv_progress(lev+3,0,"Trying to determine the file type"); + (*result)->object->type = psiconv_determine_embedded_object_type + (subbuf,lev+3,&res); + switch ((*result)->object->type) { + case psiconv_word_file: + if ((res = psiconv_parse_word_file(subbuf,lev+3,0, + ((psiconv_word_f *) &(*result)->object->file)))) + goto ERROR6; + break; + case psiconv_texted_file: + if ((res = psiconv_parse_texted_file(subbuf,lev+3,0, + ((psiconv_texted_f *) &(*result)->object->file)))) + goto ERROR6; + break; + case psiconv_sheet_file: + if ((res = psiconv_parse_sheet_file(subbuf,lev+3,0, + ((psiconv_sheet_f *) &(*result)->object->file)))) + goto ERROR6; + break; + case psiconv_sketch_file: + if ((res = psiconv_parse_sketch_file(subbuf,lev+3,0, + ((psiconv_sketch_f *) &(*result)->object->file)))) + goto ERROR6; + break; + default: + psiconv_warn(lev+3,0,"Can't parse embedded object (still continuing)"); + (*result)->object->file = NULL; + } + } + + if (length) + *length = len; + + psiconv_progress(lev+1,off+len-1,"End of Embedded Object Section " + "(total length: %08x)",len); + + return res; + + +ERROR6: + free((*result)->object); +ERROR5: + psiconv_buffer_free(subbuf); +ERROR4: + psiconv_free_object_icon_section((*result)->icon); +ERROR3: + psiconv_free_object_display_section((*result)->display); +ERROR2: + psiconv_free_section_table_section(table); +ERROR1: + psiconv_warn(lev+1,off,"Reading Embedded Object failed"); + + if (length) + *length = 0; + + if (res == 0) + return -PSICONV_E_NOMEM; + else + return res; +} + +psiconv_file_type_t psiconv_determine_embedded_object_type + (const psiconv_buffer buf,int lev, + int *status) +{ + psiconv_u32 off; + psiconv_section_table_section table; + int res,i; + psiconv_file_type_t file_type = psiconv_unknown_file; + psiconv_section_table_entry entry; + psiconv_application_id_section applid; + + psiconv_progress(lev+1,0,"Going to determine embedded object file type"); + psiconv_progress(lev+2,0,"Going to read the Section Table Offset Section"); + off = psiconv_read_u32(buf,lev,0,&res); + if (res) + goto ERROR1; + psiconv_debug(lev+2,0,"Offset: %08x",off); + + psiconv_progress(lev+2,off,"Going to read the Section Table Section"); + if ((res = psiconv_parse_section_table_section(buf,lev+2,off,NULL,&table))) + goto ERROR1; + + psiconv_progress(lev+2,off,"Going to search the Section Table Section " + "for the Application ID Section"); + for (i=0; i < psiconv_list_length(table); i++) { + psiconv_progress(lev+3,off,"Going to read entry %d",i); + if (!(entry = psiconv_list_get(table,i))) + goto ERROR2; + if (entry->id == PSICONV_ID_APPL_ID_SECTION) { + psiconv_progress(lev+3,off, + "Found the Application ID Section at offset %08x", + entry->offset); + off = entry->offset; + break; + } + } + if (i == psiconv_list_length(table)) { + psiconv_warn(lev+2,off,"No Application ID Section found"); + res = PSICONV_E_PARSE; + goto ERROR2; + } + + psiconv_progress(lev+2,off,"Going to read the Application ID Section"); + if ((res = psiconv_parse_application_id_section(buf,lev+2,off,NULL,&applid))) + goto ERROR2; + + switch (applid->id) { + case PSICONV_ID_WORD: file_type = psiconv_word_file; + psiconv_debug(lev+2,off,"Found a Word file"); + break; + case PSICONV_ID_TEXTED: file_type = psiconv_texted_file; + psiconv_debug(lev+2,off,"Found a TextEd file"); + break; + case PSICONV_ID_SKETCH: file_type = psiconv_sketch_file; + psiconv_debug(lev+2,off,"Found a Sketch file"); + break; + case PSICONV_ID_SHEET: file_type = psiconv_sheet_file; + psiconv_debug(lev+2,off,"Found a Sheet file"); + break; + default: psiconv_warn(lev+2,off,"Found an unknown file type"); + psiconv_debug(lev+2,off,"Found ID %08x",applid->id); + } + +ERROR2: + psiconv_free_application_id_section(applid); +ERROR1: + psiconv_free_section_table_section(table); + if (status) + *status = res; + return file_type; + +} + +int psiconv_parse_object_display_section(const psiconv_buffer buf,int lev, + psiconv_u32 off, int *length, + psiconv_object_display_section *result) +{ + int res = 0; + int len = 0; + int leng; + psiconv_u32 temp; + + psiconv_progress(lev+1,off,"Going to read the Object Display Section"); + if (!(*result = malloc(sizeof(**result)))) + goto ERROR1; + + psiconv_progress(lev+2,off+len,"Going to read the display as icon flag " + "(expecting 0x00 or 0x01)"); + temp = psiconv_read_u8(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + if (temp == 0x00) { + (*result)->show_icon = psiconv_bool_true; + psiconv_debug(lev+2,off+len,"Displayed as icon"); + } else if (temp == 0x01) { + (*result)->show_icon = psiconv_bool_false; + psiconv_debug(lev+2,off+len,"Displayed as full document"); + } else { + psiconv_warn(lev+2,off+len,"Unknown Object Display Section Icon Flag"); + psiconv_debug(lev+2,off+len,"Icon flag found: %02x",temp); + /* Improvise */ + (*result)->show_icon = (temp & 0x01?psiconv_bool_false:psiconv_bool_true); + } + len ++; + + psiconv_progress(lev+2,off+len,"Going to read the display width"); + (*result)->width = psiconv_read_length(buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR2; + psiconv_debug(lev+2,off+len,"Display width: %f cm",(*result)->width); + len += leng; + + psiconv_progress(lev+2,off+len,"Going to read the display height"); + (*result)->height = psiconv_read_length(buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR2; + psiconv_debug(lev+2,off+len,"Display length: %f cm",(*result)->height); + len += leng; + + psiconv_progress(lev+2,off+len,"Going to read unknown long (%08x expected)", + 0); + temp = psiconv_read_u32(buf,lev+2,off+len,&res); + if (temp != 0) { + psiconv_warn(lev+2,off+len,"Unknown Object Display Section final long"); + psiconv_debug(lev+2,off+len,"Long read: %08x",temp); + } + len += 4; + + if (length) + *length = len; + + psiconv_progress(lev+1,off+len-1,"End of Object Display Section " + "(total length: %08x",len); + return res; + +ERROR2: + free(*result); +ERROR1: + psiconv_warn(lev+1,off+len,"Reading of Object Display Section failed"); + if (length) + *length=0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +} + +int psiconv_parse_object_icon_section(const psiconv_buffer buf,int lev, + psiconv_u32 off, int *length, + psiconv_object_icon_section *result) +{ + int res = 0; + int len = 0; + int leng; + + psiconv_progress(lev+1,off,"Going to read the Object Icon Section"); + if (!(*result = malloc(sizeof(**result)))) + goto ERROR1; + + psiconv_progress(lev+2,off+len,"Going to read the icon name"); + (*result)->icon_name = psiconv_read_string(buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR2; + psiconv_debug(lev+2,off+len,"Icon name: %s",(*result)->icon_name); + len += leng; + + psiconv_progress(lev+2,off+len,"Going to read the icon width"); + (*result)->icon_width = psiconv_read_length(buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR3; + psiconv_debug(lev+2,off+len,"Icon width: %f cm",(*result)->icon_width); + len += leng; + + psiconv_progress(lev+2,off+len,"Going to read the icon height"); + (*result)->icon_height = psiconv_read_length(buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR3; + psiconv_debug(lev+2,off+len,"Icon length: %f cm",(*result)->icon_height); + len += leng; + + if (length) + *length = len; + + psiconv_progress(lev+1,off+len-1,"End of Object Icon Section" + "(total length: %08x",len); + return res; + +ERROR3: + free((*result)->icon_name); +ERROR2: + free(*result); +ERROR1: + psiconv_warn(lev+1,off+len,"Reading of Object Icon Section failed"); + if (length) + *length=0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +}