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
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
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();
  }
}
Exemple #4
0
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();
}
Exemple #5
0
void 
create_incl_chunk(IFFByteStream &iff, const char *chkid, const char *fileid)
{
  iff.put_chunk("INCL");
  iff.write(fileid, strlen(fileid));
  iff.close_chunk();
}
Exemple #6
0
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();
}
Exemple #7
0
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();
}
static void
display_th44(ByteStream & out_str, IFFByteStream & iff,
	     GUTF8String, size_t, DjVmInfo & djvminfo, int counter)
{
   int start_page=-1;
   if (djvminfo.dir)
   {
      GPList<DjVmDir::File> files_list=djvminfo.dir->get_files_list();
      for(GPosition pos=files_list;pos;++pos)
      {
	 GP<DjVmDir::File> frec=files_list[pos];
	 if (iff.tell()>=frec->offset &&
	     iff.tell()<frec->offset+frec->size)
	 {
	    while(pos && !files_list[pos]->is_page())
	       ++pos;
	    if (pos)
	       start_page=files_list[pos]->get_page_num();
	    break;
	 }
      }
   }
   if (start_page>=0)
      out_str.format( "Thumbnail icon for page %d", start_page+counter+1);
   else
      out_str.format( "Thumbnail icon");
}
static void
display_djvm_dirm(ByteStream & out_str, IFFByteStream & iff,
		  GUTF8String head, size_t, DjVmInfo& djvminfo, int)
{
  GP<DjVmDir> dir = DjVmDir::create();
  dir->decode(iff.get_bytestream());
  GPList<DjVmDir::File> list = dir->get_files_list();
  if (dir->is_indirect())
  {
    out_str.format( "Document directory (indirect, %d files %d pages)", 
	                  dir->get_files_num(), dir->get_pages_num());
    for (GPosition p=list; p; ++p)
      out_str.format( "\n%s%s -> %s", (const char*)head, 
                      (const char*)list[p]->get_load_name(), (const char*)list[p]->get_save_name() );
  }
  else
  {
    out_str.format( "Document directory (bundled, %d files %d pages)", 
	                  dir->get_files_num(), dir->get_pages_num());
    djvminfo.dir = dir;
    djvminfo.map.empty();
    for (GPosition p=list; p; ++p)
      djvminfo.map[list[p]->offset] = list[p];
  }
}
static void
display_text(ByteStream & out_str, IFFByteStream &iff,
	     GUTF8String, size_t, DjVmInfo&, int)
{
   out_str.format( "Hidden text");
   GUTF8String id;
   iff.short_id(id);
   out_str.format( " (text, etc.)");
}
static void
display_anno(ByteStream & out_str, IFFByteStream &iff,
	     GUTF8String, size_t, DjVmInfo&, int)
{
   out_str.format( "Page annotation");
   GUTF8String id;
   iff.short_id(id);
   out_str.format( " (hyperlinks, etc.)");
}
static void
display_incl(ByteStream & out_str, IFFByteStream & iff,
	     GUTF8String, size_t, DjVmInfo&, int)
{
   GUTF8String name;
   char ch;
   while(iff.read(&ch, 1) && ch!='\n')
     name += ch;
   out_str.format( "Indirection chunk --> {%s}", (const char *) name);
}
static void
display_fgbz(ByteStream & out_str, IFFByteStream &iff,
	     GUTF8String, size_t, DjVmInfo&, int)
{
  GP<ByteStream> gbs = iff.get_bytestream();
  int version = gbs->read8();
  int size = gbs->read16();
  out_str.format( "JB2 colors data, v%d, %d colors", 
                  version & 0x7f, size);
}
Exemple #14
0
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();
}
static void
display_djvu_info(ByteStream & out_str, IFFByteStream &iff,
		  GUTF8String, size_t size, DjVmInfo&, int)
{
  GP<DjVuInfo> ginfo=DjVuInfo::create();
  DjVuInfo &info=*ginfo;
  info.decode(*iff.get_bytestream());
  if (size >= 4)
    out_str.format( "DjVu %dx%d", info.width, info.height);
  if (size >= 5)
    out_str.format( ", v%d", info.version);
  if (size >= 8)
    out_str.format( ", %d dpi", info.dpi);
  if (size >= 9)
    out_str.format( ", gamma=%3.1f", info.gamma);
}
static void
display_iw4(ByteStream & out_str, IFFByteStream &iff,
	    GUTF8String, size_t, DjVmInfo&, int)
{
  GP<ByteStream> gbs = iff.get_bytestream();
  unsigned char serial = gbs->read8();
  unsigned char slices = gbs->read8();
  out_str.format( "IW4 data #%d, %d slices", serial+1, slices);
  if (serial == 0)
    {
      unsigned char major = gbs->read8();
      unsigned char minor = gbs->read8();
      unsigned char xhi = gbs->read8();
      unsigned char xlo = gbs->read8();
      unsigned char yhi = gbs->read8();
      unsigned char ylo = gbs->read8();
      out_str.format( ", v%d.%d (%s), %dx%d", major & 0x7f, minor,
                      (major & 0x80 ? "b&w" : "color"), 
                      (xhi<<8)+xlo, (yhi<<8)+ylo );
    }
}
Exemple #17
0
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();
  }
}
Exemple #18
0
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");
}
Exemple #19
0
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();
}