void GIFFChunk::save(IFFByteStream & istr, bool use_trick) { DEBUG_MSG("GIFFChunk::save(): saving chunk '" << get_full_name() << "'\n"); DEBUG_MAKE_INDENT(3); if (is_container()) { istr.put_chunk(get_full_name(), use_trick); if (chunks.size()) { GPosition pos; for(pos=chunks;pos;++pos) if (chunks[pos]->get_type()=="PROP") chunks[pos]->save(istr); for(pos=chunks;pos;++pos) if (chunks[pos]->get_type()!="PROP") chunks[pos]->save(istr); } else { DEBUG_MSG("but it's empty => saving empty container.\n"); } istr.close_chunk(); } else { istr.put_chunk(get_name(), use_trick); istr.get_bytestream()->writall((const char *) data, data.size()); istr.close_chunk(); } }
void create_masksub_chunks(IFFByteStream &iff, const GURL &url) { // Check and load pixmap file if (!g().stencil) G_THROW("The use of a raw ppm image requires a stencil"); GP<ByteStream> gibs=ByteStream::create(url, "rb"); ByteStream &ibs=*gibs; GP<GPixmap> graw_pm=GPixmap::create(ibs); GPixmap &raw_pm=*graw_pm; if ((int) g().stencil->get_width() != (int) raw_pm.columns()) G_THROW("Stencil and raw image have different widths!"); if ((int) g().stencil->get_height() != (int) raw_pm.rows()) G_THROW("Stencil and raw image have different heights!"); // Encode foreground { GP<GPixmap> gfg_img=GPixmap::create(); GPixmap &fg_img=*gfg_img; GP<GBitmap> fg_mask=GBitmap::create(); processForeground(&raw_pm, g().stencil, fg_img, *fg_mask); GP<IW44Image> fg_pm = IW44Image::create_encode(fg_img, fg_mask, IW44Image::CRCBfull); IWEncoderParms parms[8]; iff.put_chunk("FG44"); parms[0].slices = 100; fg_pm->encode_chunk(iff.get_bytestream(), parms[0]); iff.close_chunk(); } // Encode backgound { GP<GPixmap> gbg_img=GPixmap::create(); GPixmap &bg_img=*gbg_img; GP<GBitmap> bg_mask=GBitmap::create(); processBackground(&raw_pm, g().stencil, bg_img, *bg_mask); GP<IW44Image> bg_pm = IW44Image::create_encode(bg_img, bg_mask, IW44Image::CRCBnormal); IWEncoderParms parms[4]; parms[0].bytes = 10000; parms[0].slices = 74; iff.put_chunk("BG44"); bg_pm->encode_chunk(iff.get_bytestream(), parms[0]); iff.close_chunk(); parms[1].slices = 84; iff.put_chunk("BG44"); bg_pm->encode_chunk(iff.get_bytestream(), parms[1]); iff.close_chunk(); parms[2].slices = 90; iff.put_chunk("BG44"); bg_pm->encode_chunk(iff.get_bytestream(), parms[2]); iff.close_chunk(); parms[3].slices = 97; iff.put_chunk("BG44"); bg_pm->encode_chunk(iff.get_bytestream(), parms[3]); iff.close_chunk(); } }
void create_incl_chunk(IFFByteStream &iff, const char *chkid, const char *fileid) { iff.put_chunk("INCL"); iff.write(fileid, strlen(fileid)); iff.close_chunk(); }
void create_fgbz_chunk(IFFByteStream &iff) { int nzones = g().colorzones.size(); int npalette = g().colorpalette->size() / 3; GP<DjVuPalette> pal = DjVuPalette::create(); g().colorpalette->seek(0); pal->decode_rgb_entries(*g().colorpalette, npalette); pal->colordata.resize(0,blit_count-1); for (int d=0; d<blit_count; d++) { JB2Blit *blit = g().stencil->get_blit(d); const JB2Shape &shape = g().stencil->get_shape(blit->shapeno); GRect brect(blit->left, blit->bottom, shape.bits->columns(), shape.bits->rows()); int index = nzones; for (int i=0; i<nzones; i++) { GRect zrect = g().colorzones[i]; if (zrect.isempty() || zrect.intersect(brect, zrect)) index = i; } if (index >= npalette) G_THROW("create_fgbz_chunk: internal error"); pal->colordata[d] = index; } iff.put_chunk("FGbz"); pal->encode(iff.get_bytestream()); iff.close_chunk(); }
static void display_chunks(ByteStream & out_str, IFFByteStream &iff, const GUTF8String &head, DjVmInfo djvminfo) { size_t size; GUTF8String id, fullid; GUTF8String head2 = head + " "; GPMap<int,DjVmDir::File> djvmmap; int rawoffset; GMap<GUTF8String, int> counters; while ((size = iff.get_chunk(id, &rawoffset))) { if (!counters.contains(id)) counters[id]=0; else counters[id]++; GUTF8String msg; msg.format("%s%s [%d] ", (const char *)head, (const char *)id, size); out_str.format( "%s", (const char *)msg); // Display DJVM is when adequate if (djvminfo.dir) { GP<DjVmDir::File> rec = djvminfo.map[rawoffset]; if (rec) { GUTF8String id = rec->get_load_name(); GUTF8String title = rec->get_title(); out_str.format( "{%s}", (const char*) id); if (rec->is_include()) out_str.format(" [I]"); if (rec->is_thumbnails()) out_str.format(" [T]"); if (rec->is_shared_anno()) out_str.format(" [S]"); if (rec->is_page()) out_str.format(" [P%d]", rec->get_page_num()+1); if (id != title) out_str.format(" (%s)", (const char*)title); } } // Test chunk type iff.full_id(fullid); for (int i=0; disproutines[i].id; i++) if (fullid == disproutines[i].id || id == disproutines[i].id) { int n = msg.length(); while (n++ < 14+(int) head.length()) putchar(out_str, ' '); if (!iff.composite()) out_str.format( " "); (*disproutines[i].subr)(out_str, iff, head2, size, djvminfo, counters[id]); break; } // Default display of composite chunk out_str.format( "\n"); if (iff.composite()) display_chunks(out_str, iff, head2, djvminfo); // Terminate iff.close_chunk(); } }
void GIFFManager::load_chunk(IFFByteStream & istr, GP<GIFFChunk> chunk) { DEBUG_MSG("GIFFManager::load_chunk(): loading contents of chunk '" << chunk->get_name() << "'\n"); DEBUG_MAKE_INDENT(3); int chunk_size; GUTF8String chunk_id; while ((chunk_size=istr.get_chunk(chunk_id))) { if (istr.check_id(chunk_id)) { GP<GIFFChunk> ch=GIFFChunk::create(chunk_id); load_chunk(istr, ch); chunk->add_chunk(ch); } else { TArray<char> data(chunk_size-1); istr.get_bytestream()->readall( (char*)data, data.size()); GP<GIFFChunk> ch=GIFFChunk::create(chunk_id, data); chunk->add_chunk(ch); } istr.close_chunk(); } }
void create_raw_chunk(IFFByteStream &iff, const GUTF8String &chkid, const GURL &url) { iff.put_chunk(chkid); GP<ByteStream> ibs=ByteStream::create(url,"rb"); iff.copy(*ibs); iff.close_chunk(); }
void create_jb2_chunk(IFFByteStream &iff, const char *chkid, const GURL &url) { analyze_jb2_chunk(url); g().jb2stencil->seek(0); iff.put_chunk(chkid); iff.copy(*g().jb2stencil); iff.close_chunk(); }
void create_fg44_chunk(IFFByteStream &iff, const char *ckid, const GURL &url) { GP<ByteStream> gbs=ByteStream::create(url,"rb"); GP<IFFByteStream> gbsi=IFFByteStream::create(gbs); IFFByteStream &bsi=*gbsi; GUTF8String chkid; bsi.get_chunk(chkid); if (chkid != "FORM:PM44" && chkid != "FORM:BM44") G_THROW("djvumake: FG44 file has incorrect format (wrong IFF header)"); bsi.get_chunk(chkid); if (chkid!="PM44" && chkid!="BM44") G_THROW("djvumake: FG44 file has incorrect format (wring IFF header)"); GP<ByteStream> gmbs=ByteStream::create(); ByteStream &mbs=*gmbs; mbs.copy(*bsi.get_bytestream()); bsi.close_chunk(); if (bsi.get_chunk(chkid)) DjVuPrintErrorUTF8("%s","djvumake: FG44 file contains more than one chunk\n"); bsi.close_chunk(); mbs.seek(0); if (mbs.readall((void*)&primary, sizeof(primary)) != sizeof(primary)) G_THROW("djvumake: FG44 file is corrupted (cannot read primary header)"); if (primary.serial != 0) G_THROW("djvumake: FG44 file is corrupted (wrong serial number)"); if (mbs.readall((void*)&secondary, sizeof(secondary)) != sizeof(secondary)) G_THROW("djvumake: FG44 file is corrupted (cannot read secondary header)"); int iw = (secondary.xhi<<8) + secondary.xlo; int ih = (secondary.yhi<<8) + secondary.ylo; int red; for (red=1; red<=12; red++) if (iw==(w+red-1)/red && ih==(h+red-1)/red) break; flag_contains_fg = red; if (red>12) DjVuPrintErrorUTF8("%s","djvumake: FG44 subsampling is not in [1..12] range\n"); mbs.seek(0); iff.put_chunk(ckid); iff.copy(mbs); iff.close_chunk(); }
void create_bg44_chunk(IFFByteStream &iff, const char *ckid, GUTF8String filespec) { static GP<IFFByteStream> bg44iff; if (! bg44iff) { if (flag_contains_bg) DjVuPrintErrorUTF8("%s","djvumake: Duplicate BGxx chunk\n"); int i=filespec.rsearch(':'); for (int j=i+1; i>0 && j<(int)filespec.length(); j++) if (filespec[j] < '0' || filespec[j] > '9') i = -1; if (!i) G_THROW("djvumake: no filename specified in first BG44 specification"); GUTF8String filename=(i<0)?filespec:GUTF8String(filespec, i); const GURL::Filename::UTF8 url(filename); const GP<ByteStream> gbs(ByteStream::create(url,"rb")); if(!gbs) { G_THROW("djvumake: no such file as"+filename); } bg44iff = IFFByteStream::create(gbs); GUTF8String chkid; bg44iff->get_chunk(chkid); if (chkid != "FORM:PM44" && chkid != "FORM:BM44") G_THROW("djvumake: BG44 file has incorrect format (wrong IFF header)"); if (i>=0) filespec = i+1+(const char *)filespec; else filespec = "99"; } else { if (filespec.length() && filespec[0]!=':') G_THROW("djvumake: filename specified in BG44 refinement"); filespec = 1+(const char *)filespec; } const char *s=filespec; int nchunks = strtol((char *)s, (char **)&s, 10); if (nchunks<1 || nchunks>99) G_THROW("djvumake: invalid number of chunks in BG44 specification"); if (*s) G_THROW("djvumake: invalid BG44 specification (syntax error)"); int flag = (nchunks>=99); GUTF8String chkid; while (nchunks-->0 && bg44iff->get_chunk(chkid)) { if (chkid!="PM44" && chkid!="BM44") { DjVuPrintErrorUTF8("%s","djvumake: BG44 file contains unrecognized chunks (fixed)\n"); nchunks += 1; bg44iff->close_chunk(); continue; } GP<ByteStream> gmbs=ByteStream::create(); ByteStream &mbs=*gmbs; mbs.copy(*(bg44iff->get_bytestream())); bg44iff->close_chunk(); mbs.seek(0); if (mbs.readall((void*)&primary, sizeof(primary)) != sizeof(primary)) G_THROW("djvumake: BG44 file is corrupted (cannot read primary header)\n"); if (primary.serial == 0) { if (mbs.readall((void*)&secondary, sizeof(secondary)) != sizeof(secondary)) G_THROW("djvumake: BG44 file is corrupted (cannot read secondary header)\n"); int iw = (secondary.xhi<<8) + secondary.xlo; int ih = (secondary.yhi<<8) + secondary.ylo; int red; for (red=1; red<=12; red++) if (iw==(w+red-1)/red && ih==(h+red-1)/red) break; flag_contains_bg = red; if (red>12) DjVuPrintErrorUTF8("%s","djvumake: BG44 subsampling is not in [1..12] range\n"); } mbs.seek(0); iff.put_chunk(ckid); iff.copy(mbs); iff.close_chunk(); flag = 1; } if (!flag) DjVuPrintErrorUTF8("%s","djvumake: no more chunks in BG44 file\n"); }
void create_info_chunk(IFFByteStream &iff, GArray<GUTF8String> &argv) { const int argc=argv.hbound()+1; // Process info specification for (int i=2; i<argc; i++) if (!argv[i].cmp("INFO=",5)) { int narg = 0; const char *ptr = 5+(const char *)argv[i]; while (*ptr) { if (*ptr != ',') { int x = strtol((char *)ptr, (char **)&ptr, 10); switch(narg) { case 0: w = x; break; case 1: h = x; break; case 2: dpi = x; break; default: G_THROW("djvumake: incorrect 'INFO' chunk specification\n"); } } narg++; if (*ptr && *ptr++!=',') G_THROW("djvumake: comma expected in 'INFO' chunk specification\n"); } break; } if (w>0 && (w<=0 || w>=32768)) G_THROW("djvumake: incorrect width in 'INFO' chunk specification\n"); if (h>0 && (h<=0 || h>=32768)) G_THROW("djvumake: incorrect height in 'INFO' chunk specification\n"); if (dpi>0 && (dpi<25 || dpi>6000)) G_THROW("djvumake: incorrect dpi in 'INFO' chunk specification\n"); // Search first mask chunks if size is still unknown if (h<0 || w<0) { for (int i=2; i<argc; i++) if (!argv[i].cmp("Sjbz=",5)) { analyze_jb2_chunk(GURL::Filename::UTF8(5+(const char *)argv[i])); break; } else if (!argv[i].cmp("Smmr=",5)) { analyze_mmr_chunk(GURL::Filename::UTF8(5+(const char *)argv[i])); break; } } // Check that we have everything if (w<0 || h<0) G_THROW("djvumake: cannot determine image size\n"); // write info chunk GP<DjVuInfo> ginfo=DjVuInfo::create(); DjVuInfo &info=*ginfo; info.width = w; info.height = h; info.dpi = dpi; iff.put_chunk("INFO"); info.encode(*iff.get_bytestream()); iff.close_chunk(); }