--- psiconv/trunk/lib/psiconv/parse_image.c 1999/10/11 15:17:17 11 +++ psiconv/trunk/lib/psiconv/parse_image.c 1999/10/29 21:14:58 24 @@ -23,13 +23,48 @@ #include "data.h" #include "parse_routines.h" +int psiconv_parse_mbm_jumptable_section(const psiconv_buffer buf,int lev, + psiconv_u32 off, int *length, + psiconv_mbm_jumptable_section *result) +{ + int res = 0; + int len = 0; + psiconv_u32 listlen,temp; + int i; + + psiconv_progress(lev+1,off+len,"Going to read the mbm jumptable section"); + (*result) = psiconv_list_new(sizeof(psiconv_u32)); + + psiconv_progress(lev+2,off+len,"Going to read the list length"); + listlen = psiconv_read_u32(buf,lev+2,off+len); + psiconv_debug(lev+2,off+len,"List length: %08x",listlen); + len += 4; + + psiconv_progress(lev+2,off+len,"Going to read the list"); + for (i = 0; i < listlen; i++) { + temp = psiconv_read_u32(buf,lev+2,off+len); + psiconv_list_add(*result,&temp); + psiconv_debug(lev+3,off+len,"Offset: %08x",temp); + len += 4; + } + + if (length) + *length = len; + + psiconv_progress(lev+1,off+len-1,"End of mbm jumptable section " + "(total length: %08x)", len); + + return res; +} + int psiconv_parse_paint_data_section(const psiconv_buffer buf,int lev, psiconv_u32 off, int *length, psiconv_paint_data_section *result) { int res = 0; int len = 0; - psiconv_u32 size,offset,picsize,temp,datasize,pixelnr,datanr; + int read_err = 0; + psiconv_u32 size,offset,picsize,temp,datasize,pixelnr,datanr,linelen; psiconv_u8 marker; int i; @@ -43,11 +78,12 @@ psiconv_progress(lev+2,off+len,"Going to read pixel data offset"); offset = psiconv_read_u32(buf,lev+2,off+len); - if (size != 0x28) { + if (offset != 0x28) { psiconv_warn(lev+2,off+len, "Paint data section data offset has unexpected value"); psiconv_debug(lev+2,off+len, "Data offset: read %08x, expected %08x",offset,0x28); + res = -1; } len += 4; @@ -61,16 +97,19 @@ psiconv_debug(lev+2,off+len,"Picture Y size: %08x:",(*result)->ysize); len += 4; - picsize = (*result)->ysize * (*result)->xsize; + picsize = (*result)->ysize * (*result)->xsize * 2; + linelen = (*result)->xsize; - psiconv_progress(lev+2,off+len,"Going to read 6 unused longs"); + psiconv_progress(lev+2,off+len,"Going to read 6 unknown longs"); for (i = 0 ; i < 6; i++) { temp = psiconv_read_u32(buf,lev+2,off+len); - if (temp != 0x00) { + if (temp != (i==2?0x02:i==5?0x01:0x00)) { psiconv_warn(lev+2,off+len, "Paint data section prologue has unknown values"); psiconv_debug(lev+2,off+len, - "offset %02x: read %08x, expected %08x",i,temp,0x00); + "offset %02x: read %08x, expected %08x",i,temp, + i==2?0x02:i==5?0x01:0x00); + res = -1; } len += 4; } @@ -92,78 +131,271 @@ datanr ++; if (marker >= 0x80) { /* 0x100 - marker bytes of data follow */ - if ((0x100 - marker + datanr > datasize) || - ((0x100 - marker) * 4 + pixelnr > picsize)) { - psiconv_warn(lev+3,off+len+datanr,"Corrupted picture data"); - psiconv_debug(lev+3,off+len+datanr, - "Picsize: %08x, Datasize: %08x, Pixelnr: %08x," - "Datanr: %08x, marker: %02x",picsize,datasize,pixelnr, - datanr,marker); - } else { - for (i = 0; i < 0x100-marker; i++) { - temp = psiconv_read_u8(buf,lev+3,off+len+datanr+i); - (*result)->red[pixelnr + i*4] = - (*result)->green[pixelnr + i*4] = - (*result)->blue[pixelnr + i*4] = - (temp & 0x03) * (1.0/3.0); - (*result)->red[pixelnr + i*4 + 1] = - (*result)->green[pixelnr + i*4 +1] = - (*result)->blue[pixelnr + i*4 + 1] = - ((temp >> 2) & 0x03) * (1.0/3.0); - (*result)->red[pixelnr + i*4 + 2] = - (*result)->green[pixelnr + i*4 +2] = - (*result)->blue[pixelnr + i*4 + 2] = - ((temp >> 4) & 0x03) * (1.0/3.0); - (*result)->red[pixelnr + i*4 + 3] = - (*result)->green[pixelnr + i*4 +3] = - (*result)->blue[pixelnr + i*4 + 3] = - ((temp >> 6) & 0x03) * (1.0/3.0); + for (i = 0; i < 0x100-marker; i++,datanr++) { + if ((picsize == pixelnr) || (datasize == datanr)) { + psiconv_warn(lev+3,off+len+datanr,"Corrupted picture data"); + psiconv_debug(lev+3,off+len+datanr, + "Picsize: %08x, Datasize: %08x, Pixelnr: %08x," + "Datanr: %08x, marker: %02x",picsize,datasize,pixelnr, + datanr,marker); + read_err = 1; + res = -1; + break; } + temp = psiconv_read_u8(buf,lev+3,off+len+datanr); + (*result)->red[pixelnr] = + (*result)->green[pixelnr] = + (*result)->blue[pixelnr] = + (temp & 0x03) * (1.0/3.0); + pixelnr ++; + if (pixelnr % linelen == 0) + continue; + (*result)->red[pixelnr] = + (*result)->green[pixelnr] = + (*result)->blue[pixelnr] = + ((temp >> 2) & 0x03) * (1.0/3.0); + pixelnr ++; + if (pixelnr % linelen == 0) + continue; + (*result)->red[pixelnr] = + (*result)->green[pixelnr] = + (*result)->blue[pixelnr] = + ((temp >> 4) & 0x03) * (1.0/3.0); + pixelnr ++; + if (pixelnr % linelen == 0) + continue; + (*result)->red[pixelnr] = + (*result)->green[pixelnr] = + (*result)->blue[pixelnr] = + ((temp >> 6) & 0x03) * (1.0/3.0); } - pixelnr += (0x100 - marker) * 4; - datanr += (0x100 - marker); - } else { /* marker < 0x080 */ - if ((datanr + 1 > datasize) || - (marker * 4 + pixelnr > picsize)) { + } else { /* marker < 0x080 */ + if (datasize == datanr) { psiconv_warn(lev+3,off+len+datanr,"Corrupted picture data"); psiconv_debug(lev+3,off+len+datanr, "Picsize: %08x, Datasize: %08x, Pixelnr: %08x," "Datanr: %08x, marker: %02x",picsize,datasize,pixelnr, datanr,marker); + read_err = 1; + res = -1; } else { temp = psiconv_read_u8(buf,lev+3,off+len+datanr); - for (i = 0; i < marker; i++) { - (*result)->red[pixelnr + i*4] = - (*result)->green[pixelnr + i*4] = - (*result)->blue[pixelnr + i*4] = - (temp & 0x03) * (1.0/3.0); - (*result)->red[pixelnr + i*4 + 1] = - (*result)->green[pixelnr + i*4 +1] = - (*result)->blue[pixelnr + i*4 + 1] = - ((temp >> 2) & 0x03) * (1.0/3.0); - (*result)->red[pixelnr + i*4 + 2] = - (*result)->green[pixelnr + i*4 +2] = - (*result)->blue[pixelnr + i*4 + 2] = - ((temp >> 4) & 0x03) * (1.0/3.0); - (*result)->red[pixelnr + i*4 + 3] = - (*result)->green[pixelnr + i*4 +3] = - (*result)->blue[pixelnr + i*4 + 3] = - ((temp >> 6) & 0x03) * (1.0/3.0); + for (i = 0; i <= marker; i++) { + if (picsize == pixelnr) { + psiconv_warn(lev+3,off+len+datanr,"Corrupted picture data"); + psiconv_debug(lev+3,off+len+datanr, + "Picsize: %08x, Datasize: %08x, Pixelnr: %08x," + "Datanr: %08x, marker: %02x",picsize,datasize,pixelnr, + datanr,marker); + read_err = 1; + res = -1; + break; + } + (*result)->red[pixelnr] = + (*result)->green[pixelnr] = + (*result)->blue[pixelnr] = + (temp & 0x03) * (1.0/3.0); + pixelnr ++; + if (pixelnr % linelen == 0) + continue; + (*result)->red[pixelnr] = + (*result)->green[pixelnr] = + (*result)->blue[pixelnr] = + ((temp >> 2) & 0x03) * (1.0/3.0); + pixelnr ++; + if (pixelnr % linelen == 0) + continue; + (*result)->red[pixelnr] = + (*result)->green[pixelnr] = + (*result)->blue[pixelnr] = + ((temp >> 4) & 0x03) * (1.0/3.0); + pixelnr ++; + if (pixelnr % linelen == 0) + continue; + (*result)->red[pixelnr] = + (*result)->green[pixelnr] = + (*result)->blue[pixelnr] = + ((temp >> 6) & 0x03) * (1.0/3.0); + pixelnr ++; } } - pixelnr += marker * 4; datanr += 1; } } + if (!read_err && ((datanr != datasize) || (pixelnr != picsize))) { + psiconv_warn(lev+2,off+len,"Corrupted picture data!"); + psiconv_debug(lev+3,off+len+datanr, + "Picsize: %08x, Datasize: %08x, Pixelnr: %08x," + "Datanr: %08x",picsize,datasize,pixelnr,datanr); + res = -1; + } + len += datanr; if (length) *length = len; psiconv_progress(lev+1,off+len-1,"End of paint data section " - "(total length: %08x", len); + "(total length: %08x)", len); return res; } + + +int psiconv_parse_sketch_section(const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, int is_object, + psiconv_sketch_section *result) +{ + int res=0; + int len=0; + psiconv_u32 temp; + int leng; + int i; + + psiconv_progress(lev+1,off,"Going to read the sketch section"); + *result = malloc(sizeof(**result)); + + if (!is_object) { + psiconv_progress(lev+2,off+len,"Going to read the form hor. size"); + (*result)->form_xsize = psiconv_read_u16(buf,lev+2,off + len); + psiconv_debug(lev+2,off+len,"Form hor. size: %04x", + (*result)->form_xsize); + len += 0x02; + psiconv_progress(lev+2,off+len,"Going to read the form ver. size"); + (*result)->form_ysize = psiconv_read_u16(buf,lev+2,off + len); + psiconv_debug(lev+2,off+len,"Form ver. size: %04x", + (*result)->form_ysize); + len += 0x02; + psiconv_progress(lev+2,off+len,"Going to read the picture hor. offset"); + (*result)->picture_x_offset = psiconv_read_u16(buf,lev+2,off + len); + psiconv_debug(lev+2,off+len,"Picture hor. offset: %04x", + (*result)->picture_x_offset); + len += 0x02; + psiconv_progress(lev+2,off+len,"Going to read the picture ver. offset"); + (*result)->picture_y_offset = psiconv_read_u16(buf,lev+2,off + len); + psiconv_debug(lev+2,off+len,"Picture ver. offset: %04x", + (*result)->picture_y_offset); + len += 0x02; + psiconv_progress(lev+2,off+len,"Going to skip 5 words of zeros"); + for (i = 0; i < 5; i++) { + temp = psiconv_read_u16(buf,lev+2,off+len); + if (temp != 0) { + psiconv_warn(lev+2,off+len, + "Unexpected value in sketch section preamble"); + psiconv_debug(lev+2,off+len,"Word %d: Read %04x, expected %04x",i, + temp,0); + res = -1; + } + off += 0x02; + } + } else { + psiconv_progress(lev+2,off+len,"Going to read the displayed hor. size"); + (*result)->picture_xsize = psiconv_read_u16(buf,lev+2,off + len); + psiconv_debug(lev+2,off+len,"Displayed hor. size: %04x", + (*result)->picture_xsize); + len += 0x02; + psiconv_progress(lev+2,off+len,"Going to read the displayed ver. size"); + (*result)->picture_ysize = psiconv_read_u16(buf,lev+2,off + len); + psiconv_debug(lev+2,off+len,"Displayed ver. size: %04x", + (*result)->picture_ysize); + len += 0x02; + + psiconv_progress(lev+2,off+len,"Going to skip 2 words of zeros"); + for (i = 0; i < 2; i++) { + temp = psiconv_read_u16(buf,lev+2,off+len); + if (temp != 0) { + psiconv_warn(lev+2,off+len, + "Unexpected value in sketch section preamble"); + psiconv_debug(lev+2,off+len,"Word %d: Read %04x, expected %04x",i, + temp,0); + res = -1; + } + off += 0x02; + } + psiconv_progress(lev+2,off+len,"Going to read the picture hor. offset"); + (*result)->picture_x_offset = psiconv_read_u16(buf,lev+2,off + len); + psiconv_debug(lev+2,off+len,"Picture hor. offset: %04x", + (*result)->picture_x_offset); + len += 0x02; + psiconv_progress(lev+2,off+len,"Going to read the picture ver. offset"); + (*result)->picture_y_offset = psiconv_read_u16(buf,lev+2,off + len); + psiconv_debug(lev+2,off+len,"Picture ver. offset: %04x", + (*result)->picture_y_offset); + len += 0x02; + psiconv_progress(lev+2,off+len,"Going to read the form hor. size"); + (*result)->form_xsize = psiconv_read_u16(buf,lev+2,off + len); + psiconv_debug(lev+2,off+len,"Form hor. size: %04x", + (*result)->form_xsize); + len += 0x02; + psiconv_progress(lev+2,off+len,"Going to read the form ver. size"); + (*result)->form_ysize = psiconv_read_u16(buf,lev+2,off + len); + psiconv_debug(lev+2,off+len,"Form ver. size: %04x", + (*result)->form_ysize); + len += 0x02; + psiconv_progress(lev+2,off+len,"Going to skip 1 zero word"); + temp = psiconv_read_u16(buf,lev+2,off+len); + if (temp != 0) { + psiconv_warn(lev+2,off+len, + "Unexpected value in sketch section preamble"); + psiconv_debug(lev+2,off+len,"Read %04x, expected %04x",i, temp,0); + res = -1; + } + off += 0x02; + } + + psiconv_progress(lev+2,off+len,"Going to read the picture data"); + res |= psiconv_parse_paint_data_section(buf,lev+2,off+len,&leng, + &((*result)->picture)); + off += leng; + if (!is_object) { + (*result)->picture_xsize = (*result)->picture->xsize; + (*result)->picture_ysize = (*result)->picture->ysize; + } + + psiconv_progress(lev+2,off+len,"Going to read the hor. magnification"); + (*result)->magnification_x = psiconv_read_u16(buf,lev+2,off + len) / 1000.0; + psiconv_debug(lev+2,off+len,"Form hor. magnification: %f", + (*result)->magnification_x); + len += 0x02; + psiconv_progress(lev+2,off+len,"Going to read the ver. magnification"); + (*result)->magnification_y = psiconv_read_u16(buf,lev+2,off + len) / 1000.0; + psiconv_debug(lev+2,off+len,"Form ver. magnification: %f", + (*result)->magnification_y); + len += 0x02; + + psiconv_progress(lev+2,off+len,"Going to read the left cut"); + temp = psiconv_read_u32(buf,lev+2,off + len); + (*result)->cut_left = (temp * 6.0) / (*result)->picture_xsize; + psiconv_debug(lev+2,off+len,"Left cut: raw %08x, real: %f", + temp,(*result)->cut_left); + len += 0x04; + psiconv_progress(lev+2,off+len,"Going to read the right cut"); + temp = psiconv_read_u32(buf,lev+2,off + len); + (*result)->cut_right = (temp * 6.0) / (*result)->picture_xsize; + psiconv_debug(lev+2,off+len,"Right cut: raw %08x, real: %f", + temp,(*result)->cut_right); + len += 0x04; + psiconv_progress(lev+2,off+len,"Going to read the top cut"); + temp = psiconv_read_u32(buf,lev+2,off + len); + (*result)->cut_top = (temp * 6.0) / (*result)->picture_ysize; + psiconv_debug(lev+2,off+len,"Top cut: raw %08x, real: %f", + temp,(*result)->cut_top); + len += 0x04; + psiconv_progress(lev+2,off+len,"Going to read the bottom cut"); + temp = psiconv_read_u32(buf,lev+2,off + len); + (*result)->cut_bottom = (temp * 6.0) / (*result)->picture_ysize; + psiconv_debug(lev+2,off+len,"Bottom cut: raw %08x, real: %f", + temp,(*result)->cut_bottom); + len += 0x04; + + if (length) + *length = len; + + psiconv_progress(lev,off+len-1, + "End of sketch section (total length: %08x)", len); + + return res; +} +