Logo Search packages:      
Sourcecode: djvulibre version File versions

void IFFByteStream::put_chunk ( const char *  chkid,
int  insertmagic = 0 
)

Enters a chunk for writing. Function put_chunk# prepares a chunk header and positions the IFFByteStream at the beginning of the chunk data. Argument chkid# defines a extended chunk identifier for this chunk. The chunk data can then be written using function write#. The chunk is terminated by a matching call to function close_chunk#. When insertmagic# is non zero, function put_chunk# inserts the bytes: 0x41, 0x54, 0x26, 0x54 before the chunk header, as discussed in {IFFByteStream.h}.

Definition at line 313 of file IFFByteStream.cpp.

References check_id(), composite(), ByteStream::writall(), and ByteStream::write().

Referenced by DjVuFile::change_meta(), DjVuDocEditor::create_shared_anno_file(), DjVuAnno::encode(), IWPixmap::Encode::encode_iff(), IWBitmap::Encode::encode_iff(), DjVuFile::insert_file(), DjVuFile::remove_anno(), DjVuFile::remove_meta(), DjVuFile::remove_text(), GIFFChunk::save(), DjVuDocEditor::save_as(), DjVuFile::unlink_file(), DjVmDoc::write(), and DjVmDoc::write_index().

{
  int bytes;
  char buffer[8];

  // Check that we are allowed to write a chunk
  if (dir < 0)
    G_THROW( ERR_MSG("IFFByteStream.read_write") );
  if (ctx && !ctx->bComposite)
    G_THROW( ERR_MSG("IFFByteStream.not_ready2") );
  dir = +1;

  // Check primary id
  int composite = check_id(chkid);
  if ((composite<0) || (composite==0 && chkid[4])
      || (composite && (chkid[4]!=':' || check_id(&chkid[5]) || chkid[9])) )
    G_THROW( ERR_MSG("IFFByteStream.bad_chunk") );

  // Write padding byte
  assert(seekto <= offset);
  memset((void*)buffer, 0, 8);
  if (offset & 1)
    offset += bs->write((void*)&buffer[4], 1);

  // Insert magic to make this file recognizable as DjVu
  if (insert_magic)
  {
    // Don't change the way you do the file magic!
    // I rely on these bytes letters in some places
    // (like DjVmFile.cpp and djvm.cpp) -- eaf
    buffer[0]=0x41;
    buffer[1]=0x54;
    buffer[2]=0x26;
    buffer[3]=0x54;
    offset += bs->writall((void*)&buffer[0], 4);
  }

  // Write chunk header
  memcpy((void*)&buffer[0], (void*)&chkid[0], 4);
  bytes = bs->writall((void*)&buffer[0], 8);
  offset = seekto = offset + bytes;
  if (composite)
  {
    memcpy((void*)&buffer[4], (void*)&chkid[5], 4);
    bytes = bs->writall((void*)&buffer[4], 4);
    offset = offset + bytes;    
  }

  // Create new context record
  IFFContext *nctx = new IFFContext;
  G_TRY
  {
    nctx->next = ctx;
    nctx->offStart = seekto;
    nctx->offEnd = 0;
    if (composite)
    {
      memcpy( (void*)(nctx->idOne), (void*)&buffer[0], 4);
      memcpy( (void*)(nctx->idTwo), (void*)&buffer[4], 4);
      nctx->bComposite = 1;
    }
    else
    {
      memcpy( (void*)(nctx->idOne), (void*)&buffer[0], 4);
      memset( (void*)(nctx->idTwo), 0, 4);
      nctx->bComposite = 0;
    }
  }
  G_CATCH_ALL
  {
    delete nctx;
    G_RETHROW;
  }
  G_ENDCATCH; 
  // Install context record and leave
  ctx = nctx;
}


Generated by  Doxygen 1.6.0   Back to index