00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 #include "pent_include.h"
00020 #include "ConvertShape.h"
00021 
00022 #include "IDataSource.h"
00023 #include "ODataSource.h"
00024 
00025 #include <cstring>
00026 
00027 
00028 
00029 #ifdef COMP_SHAPENUM
00030 extern int shapenum;
00031 #endif
00032 
00033 void ConvertShape::Read(IDataSource *source, const ConvertShapeFormat *csf, uint32 real_len)
00034 {
00035         
00036         uint32 start_pos = source->getPos();
00037 
00038         
00039         if (csf->bytes_ident)
00040         {
00041                 char ident[4];
00042                 source->read(ident, csf->bytes_ident);
00043 
00044                 if (std::memcmp (ident, csf->ident, csf->bytes_ident))
00045                 {
00046                         perr << "Warning: Corrupt shape!" << std::endl;
00047                         return;
00048                 }
00049         }
00050 
00051         
00052         uint8 special[256];
00053         if (csf->bytes_special) {
00054                 memset(special, 0, 256);
00055                 for (uint32 i = 0; i < csf->bytes_special; i++) special[source->read1()&0xFF] = i+2;
00056         }
00057 
00058         
00059         if (csf->bytes_header_unk) source->read(header_unknown, csf->bytes_header_unk);
00060 
00061 #ifdef COMP_SHAPENUM
00062         if (shapenum == COMP_SHAPENUM) pout << std::hex;
00063 #endif
00064 
00065         
00066         num_frames = 1;
00067         if (csf->bytes_num_frames) num_frames = source->readX(csf->bytes_num_frames);
00068         if (num_frames == 0) num_frames = CalcNumFrames(source,csf,real_len,start_pos);
00069 
00070 #ifdef COMP_SHAPENUM
00071         if (shapenum == COMP_SHAPENUM) pout << "num_frames " << num_frames << std::endl;
00072 #endif
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082         
00083         frames = new ConvertShapeFrame[num_frames];
00084         std::memset (frames, 0, num_frames * sizeof(ConvertShapeFrame));
00085 
00086         
00087         for(uint32 f = 0; f < num_frames; ++f) 
00088         {
00089 #ifdef COMP_SHAPENUM
00090                 if (shapenum == COMP_SHAPENUM) pout << "Frame " << f << std::endl;
00091 #endif
00092                 ConvertShapeFrame *frame = frames+f;
00093 
00094 #ifdef COMP_SHAPENUM
00095                 if (shapenum == COMP_SHAPENUM) pout << "Seeking to " << (csf->len_header + (csf->len_frameheader*f)) << std::endl;
00096                 if (shapenum == COMP_SHAPENUM) pout << "Real " << (start_pos + csf->len_header + (csf->len_frameheader*f)) << std::endl;
00097 #endif
00098                 
00099                 source->seek(start_pos + csf->len_header + (csf->len_frameheader*f));
00100 
00101 #ifdef COMP_SHAPENUM
00102                 if (shapenum == COMP_SHAPENUM) pout << "seeked to " << source->getPos() << std::endl;
00103 #endif
00104 
00105                 
00106                 uint32 frame_offset = csf->len_header + (csf->len_frameheader*f);
00107                 if (csf->bytes_frame_offset) frame_offset = source->readX(csf->bytes_frame_offset);
00108 #ifdef COMP_SHAPENUM
00109                 if (shapenum == COMP_SHAPENUM) pout << "frame_offset " << frame_offset << std::endl;
00110 #endif
00111 
00112                 
00113                 if (csf->bytes_frameheader_unk) source->read(frame->header_unknown, csf->bytes_frameheader_unk);
00114 
00115                 
00116                 uint32 frame_length = real_len-frame_offset;
00117                 if (csf->bytes_frame_length) frame_length = source->readX(csf->bytes_frame_length) + csf->bytes_frame_length_kludge;
00118 #ifdef COMP_SHAPENUM
00119                 if (shapenum == COMP_SHAPENUM) pout << "frame_length " << frame_length << std::endl;
00120 #endif
00121 
00122                 
00123                 source->seek(start_pos + frame_offset + csf->bytes_special);
00124 
00125                 if (csf->bytes_special)
00126                         frame->ReadCmpFrame(source, csf, special, f>0?frames+f-1:0);
00127                 else 
00128                         frame->Read(source, csf, frame_length);
00129         }
00130 
00131 #ifdef COMP_SHAPENUM
00132         if (shapenum == COMP_SHAPENUM) pout << std::dec;
00133 #endif
00134 }
00135 
00136 void ConvertShapeFrame::Read(IDataSource *source, const ConvertShapeFormat *csf, uint32 frame_length)
00137 {
00138         
00139         if (csf->bytes_frame_unknown) source->read(unknown, csf->bytes_frame_unknown);
00140 
00141         
00142         compression = source->readX(csf->bytes_frame_compression);
00143         width = source->readXS(csf->bytes_frame_width);
00144         height = source->readXS(csf->bytes_frame_height);
00145         xoff = source->readXS(csf->bytes_frame_xoff);
00146         yoff = source->readXS(csf->bytes_frame_yoff);
00147 
00148 #ifdef COMP_SHAPENUM
00149         if (width <= 0 || height <= 0  ||shapenum == COMP_SHAPENUM )
00150         {
00151                 pout << "compression " << compression << std::endl;
00152                 pout << "width " << width << std::endl;
00153                 pout << "height " << height << std::endl;
00154                 pout << "xoff " << xoff << std::endl;
00155                 pout << "yoff " << yoff << std::endl;
00156         }
00157 #endif
00158 
00159         if (compression != 0 && compression != 1) {
00160                 compression = 0;
00161                 width = 0;
00162                 height = 0;
00163                 xoff = 0;
00164                 yoff = 0;
00165                 
00166                 perr << "Corrupt frame?" << std::endl;
00167         }
00168 
00169         if (height) {
00170                 
00171                 line_offsets = new uint32 [height];
00172 
00173                 for(sint32 i = 0; i < height; ++i) 
00174                 {
00175                         line_offsets[i] = source->readX(csf->bytes_line_offset);
00176 
00177                         
00178                         
00179                         if (!csf->line_offset_absolute) 
00180                                 line_offsets[i] -= (height-i)*csf->bytes_line_offset;
00181                 }
00182 
00183                 
00184                 bytes_rle = frame_length - (csf->len_frameheader2+(height*csf->bytes_line_offset));
00185 
00186 #ifdef COMP_SHAPENUM
00187                 if (bytes_rle < 0)
00188                 {
00189                         bytes_rle = 0;
00190                         perr << "Corrupt frame?" << std::endl;
00191                 }
00192                 
00193 #endif
00194         }
00195         else 
00196                 line_offsets = 0;
00197 
00198         
00199         if (bytes_rle) {
00200                 rle_data = new uint8[bytes_rle];
00201                 source->read(rle_data, bytes_rle);
00202         }
00203         else 
00204                 rle_data = 0;
00205 }
00206 
00207 void ConvertShapeFrame::ReadCmpFrame(IDataSource *source, const ConvertShapeFormat *csf, const uint8 special[256], ConvertShapeFrame *prev)
00208 {
00209         static OAutoBufferDataSource *rlebuf = 0;
00210         uint8 outbuf[512];
00211 
00212         
00213         if (csf->bytes_frame_unknown) source->read(unknown, csf->bytes_frame_unknown);
00214 
00215         
00216         compression = source->readX(csf->bytes_frame_compression);
00217         width = source->readXS(csf->bytes_frame_width);
00218         height = source->readXS(csf->bytes_frame_height);
00219         xoff = source->readXS(csf->bytes_frame_xoff);
00220         yoff = source->readXS(csf->bytes_frame_yoff);
00221 
00222         line_offsets = new uint32 [height];
00223 
00224         if (!rlebuf) rlebuf = new OAutoBufferDataSource(1024);
00225         rlebuf->clear();
00226 
00227         for(sint32 y = 0; y < height; ++y) 
00228         {
00229                 line_offsets[y] = rlebuf->getPos();
00230 
00231                 sint32 xpos = 0;
00232 
00233                 do
00234                 {
00235                         uint8 skip = source->read1();
00236                         xpos += skip;
00237 
00238                         if (xpos > width) {
00239                                 source->skip(-1); 
00240                                 skip = width-(xpos-skip);
00241                         }
00242 
00243                         rlebuf->write1(skip);
00244 
00245                         if (xpos >= width) break;
00246 
00247                         uint32 dlen = source->read1();
00248                         uint8 *o = outbuf;
00249 
00250                         
00251                         if (dlen == 0 || dlen == 1) {
00252                                 source->skip(-1); 
00253                                 rlebuf->skip(-1);
00254                                 rlebuf->write1(skip+(width-xpos));
00255                                 break;
00256                         }
00257 
00258                         int type = 0;
00259                         
00260                         if (compression)  {
00261                                 type = dlen & 1;
00262                                 dlen >>= 1;
00263                         }
00264 
00265                         if (!type) {
00266 
00267                                 uint32 extra = 0;
00268 
00269                                 for (uint32 j = 0; j < dlen; j++) {
00270 
00271                                         uint8 c = source->read1();
00272 
00273                                         if (special[c] && prev) {
00274                                                 sint32 count = special[c];
00275                                                 prev->GetPixels(o,count,xpos-xoff,y-yoff);
00276                                                 o+=count;
00277                                                 extra += count-1;
00278                                                 xpos += count;
00279                                         }
00280                                         else if (c == 0xFF && prev) {
00281                                                 sint32 count = source->read1();
00282                                                 prev->GetPixels(o,count,xpos-xoff,y-yoff);
00283                                                 o+=count;
00284                                                 extra += count-2;
00285                                                 xpos += count;
00286                                                 j++;
00287                                         }
00288                                         else {
00289                                                 *o++ = c;
00290                                                 xpos++;
00291                                         }
00292                                 }
00293 
00294                                 if (((dlen+extra) << compression) > 255) {
00295                                         perr << "Error! Corrupt Frame. RLE dlen too large" << std::endl;
00296                                 }
00297 
00298                                 rlebuf->write1((dlen+extra) << compression);
00299                                 rlebuf->write(outbuf,dlen+extra);
00300                         }
00301                         else {
00302                                 rlebuf->write1((dlen<<1)|1);
00303                                 rlebuf->write1(source->read1());
00304                                 xpos+=dlen;
00305                         }
00306 
00307                 } while (xpos < width);
00308         }
00309 
00310         bytes_rle = rlebuf->getPos();
00311         rle_data = new uint8[bytes_rle];
00312         memcpy (rle_data, rlebuf->getBuf(), bytes_rle);
00313 }
00314 
00315 void ConvertShapeFrame::GetPixels(uint8 *buf, sint32 count, sint32 x, sint32 y)
00316 {
00317         x += xoff;
00318         y += yoff;
00319 
00320         if (y > height) return;
00321 
00322         sint32 xpos = 0;
00323         const uint8 * linedata = rle_data + line_offsets[y];
00324 
00325         do {
00326                 xpos += *linedata++;
00327           
00328                 if (xpos == width) break;
00329 
00330                 sint32 dlen = *linedata++;
00331                 int type = 0;
00332                 
00333                 if (compression) 
00334                 {
00335                         type = dlen & 1;
00336                         dlen >>= 1;
00337                 }
00338 
00339                 if (x >= xpos && x < (xpos+dlen))
00340                 {
00341                         int diff = x-xpos;
00342                         dlen-=diff;
00343                         xpos = x;
00344 
00345                         int num = count;
00346                         if (dlen < count) num = dlen;
00347 
00348                         if (!type) {
00349                                 const uint8 *l = (linedata+=diff);
00350 
00351                                 while (num--) {
00352                                         *buf++ = *l++;
00353                                         count--;
00354                                         x++;
00355                                 }
00356                         }
00357                         else {
00358                                 uint8 l = *linedata;
00359 
00360                                 while (num--) {
00361                                         *buf++ = l;
00362                                         count--;
00363                                         x++;
00364                                 }
00365                         }
00366 
00367                         if (count == 0) return;
00368                 }
00369                 
00370                 if (!type) linedata+=dlen;
00371                 else linedata++;
00372 
00373                 xpos += dlen;
00374 
00375         } while (xpos < width);
00376 }
00377 
00378 int ConvertShape::CalcNumFrames(IDataSource *source, const ConvertShapeFormat *csf, uint32 real_len, uint32 start_pos)
00379 {
00380         int f=0;
00381         uint32 first_offset = 0xFFFFFFFF;
00382 
00383         uint32 save_pos = source->getPos();
00384 
00385         for (f=0;;f++) {
00386 
00387                 
00388                 source->seek(start_pos + csf->len_header + (csf->len_frameheader*f));
00389 
00390                 if ((source->getPos()-start_pos) >= first_offset) break;
00391 
00392                 
00393                 uint32 frame_offset = csf->len_header + (csf->len_frameheader*f);
00394                 if (csf->bytes_frame_offset) frame_offset = source->readX(csf->bytes_frame_offset) + csf->bytes_special;
00395 
00396                 if (frame_offset < first_offset) first_offset = frame_offset;
00397 
00398                 
00399                 if (csf->bytes_frameheader_unk) source->skip(csf->bytes_frameheader_unk);
00400 
00401                 
00402                 uint32 frame_length = real_len-frame_offset;
00403                 if (csf->bytes_frame_length) frame_length = source->readX(csf->bytes_frame_length) + csf->bytes_frame_length_kludge;
00404         }
00405 
00406         source->seek(save_pos);
00407 
00408         return f;
00409 }
00410 
00411 bool ConvertShape::Check(IDataSource *source, const ConvertShapeFormat *csf, uint32 real_len)
00412 {
00413 #if 0
00414         pout << "Testing " << csf->name << "..." << std::endl;
00415 #endif
00416         bool result = true;
00417 
00418         
00419         int start_pos = source->getPos();
00420 
00421         
00422         if (csf->bytes_ident)
00423         {
00424                 char ident[5];
00425                 ident[csf->bytes_ident] = 0;
00426                 source->read(ident, csf->bytes_ident);
00427 
00428                 if (std::memcmp (ident, csf->ident, csf->bytes_ident))
00429                 {
00430                         
00431                         source->seek(start_pos);
00432                         return false;
00433                 }
00434         }
00435 
00436         
00437         if (csf->bytes_special) source->skip(csf->bytes_special);
00438 
00439         
00440         if (csf->bytes_header_unk) source->skip(csf->bytes_header_unk);
00441 
00442         
00443         int num_frames = 1;
00444         if (csf->bytes_num_frames) num_frames = source->readX(csf->bytes_num_frames);
00445         if (num_frames == 0) num_frames = CalcNumFrames(source,csf,real_len,start_pos);
00446 
00447         
00448         ConvertShapeFrame oneframe;
00449         std::memset (&oneframe, 0, sizeof(ConvertShapeFrame));
00450 
00451         
00452         for (int f = 0; f < num_frames; f++) 
00453         {
00454                 ConvertShapeFrame *frame = &oneframe;
00455 
00456                 
00457                 source->seek(start_pos + csf->len_header + (csf->len_frameheader*f));
00458 
00459                 
00460                 uint32 frame_offset = csf->len_header + (csf->len_frameheader*f);
00461                 if (csf->bytes_frame_offset) frame_offset = source->readX(csf->bytes_frame_offset) + csf->bytes_special;
00462 
00463                 
00464                 if (csf->bytes_frameheader_unk) source->read(frame->header_unknown, csf->bytes_frameheader_unk);
00465 
00466                 
00467                 uint32 frame_length = real_len-frame_offset;
00468                 if (csf->bytes_frame_length) frame_length = source->readX(csf->bytes_frame_length) + csf->bytes_frame_length_kludge;
00469 
00470                 
00471                 if ((frame_length + frame_offset) > real_len)
00472                 {
00473                         result = false;
00474                         break;
00475                 }
00476 
00477                 
00478                 source->seek(start_pos + frame_offset);
00479 
00480                 
00481                 if (csf->bytes_frame_unknown) source->read(frame->unknown, csf->bytes_frame_unknown);
00482 
00483                 
00484                 frame->compression = source->readX(csf->bytes_frame_compression);
00485                 frame->width = source->readXS(csf->bytes_frame_width);
00486                 frame->height = source->readXS(csf->bytes_frame_height);
00487                 frame->xoff = source->readXS(csf->bytes_frame_xoff);
00488                 frame->yoff = source->readXS(csf->bytes_frame_yoff);
00489 
00490                 if (frame->compression != 0 && frame->compression != 1 || frame->width < 0 || frame->height < 0)
00491                 {
00492                         frame->compression = 0;
00493                         frame->width = 0;
00494                         frame->height = 0;
00495                         frame->xoff = 0;
00496                         frame->yoff = 0;
00497                         result = false;
00498                         break;
00499                 }
00500 
00501                 if (frame->height)
00502                 {
00503                         
00504                         sint32 highest_offset_byte = 0;
00505 
00506                         
00507                         frame->bytes_rle = frame_length - (csf->len_frameheader2+(frame->height*csf->bytes_line_offset));
00508 
00509                         
00510                         if (frame->bytes_rle < 0)
00511                         {
00512                                 result = false;
00513                                 break;
00514                         }
00515 
00516                         
00517                         if (!csf->bytes_special) {
00518 
00519                                 
00520                                 source->seek(start_pos + frame_offset + csf->len_frameheader2);
00521 
00522                                 
00523                                 for (int i = 0; i < frame->height; i++) 
00524                                 {
00525                                         sint32 line_offset = source->readX(csf->bytes_line_offset);
00526 
00527                                         
00528                                         
00529                                         if (!csf->line_offset_absolute) 
00530                                                 line_offset -= (frame->height-i)*csf->bytes_line_offset;
00531 
00532                                         if (line_offset > frame->bytes_rle)
00533                                         {
00534                                                 result = false;
00535                                                 break;
00536                                         }
00537 
00538                                         if (line_offset > highest_offset_byte) highest_offset_byte = line_offset;
00539                                 };
00540 
00541                                 
00542                                 if (result == false) break;
00543 
00544                                 
00545                                 source->seek(highest_offset_byte + start_pos + frame_offset + csf->len_frameheader2 + frame->height*csf->bytes_line_offset);
00546                                 int xpos = 0;
00547                                 uint32 dlen = 0;
00548 
00549                                 
00550                                 if (frame->compression) do
00551                                 {
00552                                         xpos += source->read1();
00553                                         if (xpos == frame->width) break;
00554 
00555                                         dlen = source->read1();
00556                                         int type = dlen & 1;
00557                                         dlen >>= 1;
00558 
00559                                         if (!type) source->skip(dlen);
00560                                         else source->skip(1);
00561 
00562                                         xpos += dlen;
00563 
00564                                 } while (xpos < frame->width);
00565                                 
00566                                 else do
00567                                 {
00568                                         xpos += source->read1();
00569                                         if (xpos == frame->width) break;
00570 
00571                                         dlen = source->read1();
00572                                         source->skip(dlen);
00573 
00574                                         xpos += dlen;
00575                                 } while (xpos < frame->width);
00576 
00577                                 
00578                                 sint32 highest_rle_byte = source->getPos();
00579                                 highest_rle_byte -= start_pos + frame_offset + csf->len_frameheader2 + frame->height*csf->bytes_line_offset;
00580 
00581                                 
00582                                 if (highest_rle_byte > frame->bytes_rle)
00583                                 {
00584                                         result = false;
00585                                         break;
00586                                 }
00587                         }
00588                 }
00589         }
00590 
00591         
00592         oneframe.Free();
00593         num_frames = 0;
00594 
00595         
00596         source->seek(start_pos);
00597 
00598         return result;
00599 }
00600 
00601 bool ConvertShape::CheckUnsafe(IDataSource *source, const ConvertShapeFormat *csf, uint32 real_len)
00602 {
00603 #if 0
00604         pout << "Testing " << csf->name << "..." << std::endl;
00605 #endif
00606         bool result = true;
00607 
00608         
00609         int start_pos = source->getPos();
00610 
00611         
00612         if (csf->bytes_ident)
00613         {
00614                 char ident[5];
00615                 ident[csf->bytes_ident] = 0;
00616                 source->read(ident, csf->bytes_ident);
00617 
00618                 if (std::memcmp (ident, csf->ident, csf->bytes_ident))
00619                 {
00620                         
00621                         source->seek(start_pos);
00622                         return false;
00623                 }
00624         }
00625 
00626         
00627         if (csf->bytes_special) source->skip(csf->bytes_special);
00628 
00629         
00630         if (csf->bytes_header_unk) source->skip(csf->bytes_header_unk);
00631 
00632         
00633         int num_frames = 1;
00634         if (csf->bytes_num_frames) num_frames = source->readX(csf->bytes_num_frames);
00635         if (num_frames == 0) num_frames = CalcNumFrames(source,csf,real_len,start_pos);
00636 
00637         
00638         ConvertShapeFrame oneframe;
00639         std::memset (&oneframe, 0, sizeof(ConvertShapeFrame));
00640 
00641         
00642         for (int f = 0; f < num_frames; f++) 
00643         {
00644                 ConvertShapeFrame *frame = &oneframe;
00645 
00646                 
00647                 source->seek(start_pos + csf->len_header + (csf->len_frameheader*f));
00648 
00649                 
00650                 uint32 frame_offset = csf->len_header + (csf->len_frameheader*f);
00651                 if (csf->bytes_frame_offset) frame_offset = source->readX(csf->bytes_frame_offset) + csf->bytes_special;
00652 
00653                 
00654                 if (csf->bytes_frameheader_unk) source->read(frame->header_unknown, csf->bytes_frameheader_unk);
00655 
00656                 
00657                 uint32 frame_length = real_len-frame_offset;
00658                 if (csf->bytes_frame_length) frame_length = source->readX(csf->bytes_frame_length) + csf->bytes_frame_length_kludge;
00659 
00660                 
00661                 if ((frame_length + frame_offset) > real_len)
00662                 {
00663                         result = false;
00664                         break;
00665                 }
00666 
00667                 
00668                 source->seek(start_pos + frame_offset);
00669 
00670                 
00671                 if (csf->bytes_frame_unknown) source->read(frame->unknown, csf->bytes_frame_unknown);
00672 
00673                 
00674                 frame->compression = source->readX(csf->bytes_frame_compression);
00675                 frame->width = source->readXS(csf->bytes_frame_width);
00676                 frame->height = source->readXS(csf->bytes_frame_height);
00677                 frame->xoff = source->readXS(csf->bytes_frame_xoff);
00678                 frame->yoff = source->readXS(csf->bytes_frame_yoff);
00679 
00680                 if (frame->compression != 0 && frame->compression != 1 || frame->width < 0 || frame->height < 0)
00681                 {
00682                         frame->compression = 0;
00683                         frame->width = 0;
00684                         frame->height = 0;
00685                         frame->xoff = 0;
00686                         frame->yoff = 0;
00687                         result = false;
00688                         break;
00689                 }
00690 
00691                 if (frame->height)
00692                 {
00693                         
00694                         frame->bytes_rle = frame_length - (csf->len_frameheader2+(frame->height*csf->bytes_line_offset));
00695 
00696                         
00697                         if (frame->bytes_rle < 0)
00698                         {
00699                                 result = false;
00700                                 break;
00701                         }
00702                 }
00703         }
00704 
00705         
00706         oneframe.Free();
00707         num_frames = 0;
00708 
00709         
00710         source->seek(start_pos);
00711 
00712         return result;
00713 }
00714 
00715 void ConvertShape::Write(ODataSource *dest, const ConvertShapeFormat *csf, uint32 &write_len)
00716 {
00717         
00718         uint32 start_pos = dest->getPos();
00719 
00720         
00721         if (csf->bytes_ident) dest->write(csf->ident, csf->bytes_ident);
00722 
00723         
00724         if (csf->bytes_header_unk) dest->write(header_unknown, csf->bytes_header_unk);
00725 
00726         
00727         if (csf->bytes_num_frames) dest->writeX(num_frames, csf->bytes_num_frames);
00728         else if (!csf->bytes_num_frames && num_frames > 1)
00729         {
00730                 perr << "Error: Unable to convert multiple frame shapes to " << csf->name << std::endl; 
00731                 return;
00732         }
00733 
00734         
00735         for (uint32 i = 0; i < num_frames*csf->len_frameheader; i++) dest->write1(0);
00736 
00737         
00738         for(uint32 f = 0; f < num_frames; f++) 
00739         {
00740                 ConvertShapeFrame *frame = frames+f;
00741 
00742                 
00743                 uint32 frame_offset = dest->getPos() - start_pos;
00744 
00745                 
00746                 dest->seek(start_pos + csf->len_header + (csf->len_frameheader*f));
00747 
00748                 
00749                 if (csf->bytes_frame_offset) dest->writeX(frame_offset, csf->bytes_frame_offset);
00750 
00751                 
00752                 if (csf->bytes_frameheader_unk) dest->write(frame->header_unknown, csf->bytes_frameheader_unk);
00753 
00754                 
00755                 if (csf->bytes_frame_length)
00756                 {
00757                         uint32 frame_length = csf->len_frameheader2 + (frame->height*csf->bytes_line_offset) + frame->bytes_rle;
00758                         dest->writeX(frame_length - csf->bytes_frame_length_kludge, csf->bytes_frame_length);
00759                 }
00760 
00761                 
00762                 dest->seek(start_pos + frame_offset);
00763 
00764                 
00765                 if (csf->bytes_frame_unknown) dest->write(frame->unknown, csf->bytes_frame_unknown);
00766 
00767                 
00768                 dest->writeX(frame->compression, csf->bytes_frame_compression);
00769                 dest->writeX(frame->width, csf->bytes_frame_width);
00770                 dest->writeX(frame->height, csf->bytes_frame_height);
00771                 dest->writeX(frame->xoff, csf->bytes_frame_xoff);
00772                 dest->writeX(frame->yoff, csf->bytes_frame_yoff);
00773 
00774                 
00775                 for (sint32 i = 0; i < frame->height; i++) 
00776                 {
00777                         sint32 actual_offset = frame->line_offsets[i];
00778                         
00779                         
00780                         if (!csf->line_offset_absolute)  
00781                                 actual_offset += (frame->height-i)*csf->bytes_line_offset;
00782 
00783                         dest->writeX(actual_offset, csf->bytes_line_offset);
00784                 }
00785 
00786                 
00787                 dest->write(frame->rle_data, frame->bytes_rle);
00788         }
00789 
00790         
00791         write_len = dest->getPos() - start_pos;
00792 }
00793 
00794 
00795 
00796 const ConvertShapeFormat                PentagramShapeFormat =
00797 {
00798         "Pentagram",
00799         8,              
00800         "PSHP", 
00801         4,              
00802         0,              
00803         0,              
00804         4,              
00805 
00806         8,              
00807         4,              
00808         0,              
00809         4,              
00810         0,              
00811 
00812         20,             
00813         0,              
00814         4,              
00815         4,              
00816         4,              
00817         4,              
00818         4,              
00819 
00820         4,              
00821         1               
00822 };