Beispiel #1
0
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();
  }
}
Beispiel #2
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();
  }
}
Beispiel #3
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();
}
Beispiel #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();
}
Beispiel #5
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();
}
Beispiel #6
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();
}
Beispiel #7
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();
}
Beispiel #8
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");
}
Beispiel #9
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();
}