Example #1
0
static long 
calculate_buffer_size (BITS *bits)
{
    int
        block_nbr;                      /*  Bitstring block number           */
    word
        comp_size;                      /*  Size of compressed block         */
    BITBLOCK
        *block_ptr;                     /*  Points to bitstring block        */
    long
        feedback = 0;                   /*  Calulated value to return        */

    ASSERT (bits);

   
    feedback += sizeof (bits-> block_count);
    feedback += sizeof (bits-> free_list);

    /*  Write bitstring blocks to file                                       */
    for (block_nbr = 0; block_nbr < bits-> block_count; block_nbr++)
      {
        block_ptr = bits-> block [block_nbr];
        comp_size = compress_block (block_ptr-> block.data,
                                    compressed, (word)BIT_DATASIZE);
        feedback += sizeof (block_ptr-> right);
        feedback += sizeof (block_ptr-> size);
        feedback += sizeof (comp_size) + comp_size;
      }
    return (feedback);
}
Example #2
0
int
bits_fput (FILE *file,
    const BITS *bits)
{
    int
        block_nbr;                      /*  Bitstring block number           */
    word
        comp_size;                      /*  Size of compressed block         */
    BITBLOCK
        *block_ptr;                     /*  Points to bitstring block        */

    ASSERT (bits);
    ASSERT (file);

    /*  Write bitstring header to file                                       */
    fwrite (&bits-> block_count, sizeof (bits-> block_count), 1, file);
    fwrite (&bits-> free_list,   sizeof (bits-> free_list),   1, file);

    /*  Write bitstring blocks to file                                       */
    for (block_nbr = 0; block_nbr < bits-> block_count; block_nbr++)
      {
        block_ptr = bits-> block [block_nbr];
        comp_size = compress_block ((byte *) block_ptr,
                                    compressed, (word) block_ptr-> size);

        fwrite (&comp_size, sizeof (comp_size), 1, file);
        fwrite (compressed, comp_size,          1, file);
      }
    return 0;
}
Example #3
0
static void
have_end_of_block (Bool compress)
{
    output_dbyte = htons (nbr_paras);
    *(dbyte *) inbuf = output_dbyte;

    if (compress)
      {
        outsize = compress_block (inbuf, outbuf, insize);
        output_dbyte = htons (outsize);
        ASSERT (fwrite (&output_dbyte, 2, 1, scratch));
        ASSERT (fwrite (outbuf, 1, outsize, scratch));
        sizes [nbr_blocks] = outsize + 2;
      }
    else
      {
        output_dbyte = htons (insize);
        ASSERT (fwrite (&output_dbyte, 2, 1, scratch));
        ASSERT (fwrite (inbuf, 1, insize, scratch));
        sizes [nbr_blocks] = insize + 2;
      }
    insize = 2;                         /*  Clear input buffer               */
    nbr_paras = 0;
    nbr_blocks++;
}
Example #4
0
char *
bits_save (BITS *bits)
{
    int
        block_nbr;                      /*  Bitstring block number           */
    word
        comp_size;                      /*  Size of compressed block         */
    BITBLOCK
        *block_ptr;                     /*  Points to bitstring block        */
    byte
        *buffer = NULL,                 /*  Stream buffer                    */
        *position;                      /*  Current position in the stream   */
    long
        size;
    char
        *encoded = NULL;

    ASSERT (bits);

    size = calculate_buffer_size (bits);
    buffer = mem_alloc (size);
    if (buffer)
      {
        position = buffer;
        /*  Write bitstring header to stream                                 */
        *((int *)position) = bits-> block_count;
        position += sizeof (bits-> block_count);

        *((dbyte *)position) = bits-> free_list;
        position += sizeof (bits-> free_list);

        /*  Write bitstring blocks to stream                                 */
        for (block_nbr = 0; block_nbr < bits-> block_count; block_nbr++)
          {
            block_ptr = bits-> block [block_nbr];
            comp_size = compress_block (block_ptr-> block.data,
                                    compressed, (word)BIT_DATASIZE);

            *((dbyte *)position) = block_ptr-> right;
            position += sizeof (block_ptr-> right);

            *((int *)position) = block_ptr-> size;
            position += sizeof (block_ptr-> size);

            *((word *)position) = comp_size;
            position += sizeof (word);
            memcpy (position, compressed, comp_size);
            position += comp_size;
          }
        /* Encode binary buffer in base64                                    */
        encoded = mem_alloc ((long)((double) size * 1.5) + 2);
        if (encoded)
            encode_base64 (buffer, encoded, size);

        mem_free (buffer);
      }
    return (encoded);
}
Example #5
0
local
compress_file_lz (FILE *input, FILE *output)
{
    word
        in_size,
        out_size;
    qbyte
        signature = LZ_SIGNATURE;

    fseek (input, 0, SEEK_SET);         /*  Start from beginning of file     */
    ASSERT (fwrite (&signature, sizeof (signature), 1, output));
    while ((in_size = fread (in_block, 1, BLOCK_SIZE, input)) > 0)
      {
        out_size = compress_block (in_block, out_block, in_size);
        ASSERT (fwrite (&out_size, 1, sizeof (out_size), output));
        ASSERT (fwrite (out_block, 1, out_size, output));
        printf ("lz compress: in=%d out=%d\n", in_size, out_size);
      }
}
Example #6
0
int wsq_encode_mem(unsigned char **odata, int *olen, const float r_bitrate,
                   unsigned char *idata, const int w, const int h,
                   const int d, const int ppi, char *comment_text)
{
	struct wsq_data_struct * pwsq_data;
   int ret, num_pix;
   float *fdata;                 /* floating point pixel image  */
   float m_shift, r_scale;       /* shift/scale parameters      */
   short *qdata;                 /* quantized image pointer     */
   int qsize, qsize1, qsize2, qsize3;  /* quantized block sizes */
   unsigned char *huffbits, *huffvalues; /* huffman code parameters     */
   HUFFCODE *hufftable;          /* huffcode table              */
   unsigned char *huff_buf;      /* huffman encoded buffer      */
   int hsize, hsize1, hsize2, hsize3; /* Huffman coded blocks sizes */
   unsigned char *wsq_data;      /* compressed data buffer      */
   int wsq_alloc, wsq_len;       /* number of bytes in buffer   */
   int block_sizes[2];

   /* Compute the total number of pixels in image. */
   num_pix = w * h;

   /* Allocate floating point pixmap. */
   if((fdata = (float *) malloc(num_pix*sizeof(float))) == NULL) {
      fprintf(stderr,"ERROR : wsq_encode_1 : malloc : fdata\n");
      return(-10);
   }

   /* Convert image pixels to floating point. */
   if(ret = conv_img_2_flt_ret(fdata, &m_shift, &r_scale, idata, num_pix)) {
      free(fdata);
      return(ret);
   }

   if(debug > 0)
      fprintf(stderr, "Input image pixels converted to floating point\n\n");

   /* Build WSQ decomposition trees */
   build_wsq_trees(pwsq_data->w_tree, W_TREELEN, pwsq_data->q_tree, Q_TREELEN, w, h);

   if(debug > 0)
      fprintf(stderr, "Tables for wavelet decomposition finished\n\n");

   /* WSQ decompose the image */
   if((ret = wsq_decompose(fdata, w, h, pwsq_data->w_tree, W_TREELEN,
                            hifilt, MAX_HIFILT, lofilt, MAX_LOFILT))){
      free(fdata);
      return(ret);
   }

   if(debug > 0)
      fprintf(stderr, "WSQ decomposition of image finished\n\n");

   /* Set compression ratio and 'q' to zero. */
   pwsq_data->quant_vals.cr = 0;
   pwsq_data->quant_vals.q = 0.0;
   /* Assign specified r-bitrate into quantization structure. */
   pwsq_data->quant_vals.r = r_bitrate;
   /* Compute subband variances. */
   variance(&(pwsq_data->quant_vals), pwsq_data->q_tree, Q_TREELEN, fdata, w, h);

   if(debug > 0)
      fprintf(stderr, "Subband variances computed\n\n");

   /* Quantize the floating point pixmap. */
   if((ret = quantize(&qdata, &qsize, &(pwsq_data->quant_vals), pwsq_data->q_tree, Q_TREELEN,
                      fdata, w, h))){
      free(fdata);
      return(ret);
   }

   /* Done with floating point wsq subband data. */
   free(fdata);

   if(debug > 0)
      fprintf(stderr, "WSQ subband decomposition data quantized\n\n");

   /* Compute quantized WSQ subband block sizes */
   quant_block_sizes(&qsize1, &qsize2, &qsize3, &(pwsq_data->quant_vals),
                           pwsq_data->w_tree, W_TREELEN, pwsq_data->q_tree, Q_TREELEN);

   if(qsize != qsize1+qsize2+qsize3){
      fprintf(stderr,
              "ERROR : wsq_encode_1 : problem w/quantization block sizes\n");
      return(-11);
   }

   /* Allocate a WSQ-encoded output buffer.  Allocate this buffer */
   /* to be the size of the original pixmap.  If the encoded data */
   /* exceeds this buffer size, then throw an error because we do */
   /* not want our compressed data to be larger than the original */
   /* image data.                                                 */
   wsq_data = (unsigned char *)malloc(num_pix);
   if(wsq_data == (unsigned char *)NULL){
      free(qdata);
      fprintf(stderr, "ERROR : wsq_encode_1 : malloc : wsq_data\n");
      return(-12);
   }
   wsq_alloc = num_pix;
   wsq_len = 0;

   /* Add a Start Of Image (SOI) marker to the WSQ buffer. */
   if((ret = putc_ushort(SOI_WSQ, wsq_data, wsq_alloc, &wsq_len))){
      free(qdata);
      free(wsq_data);
      return(ret);
   }

   if((ret = putc_nistcom_wsq(comment_text, w, h, d, ppi, 1 /* lossy */,
                             r_bitrate, wsq_data, wsq_alloc, &wsq_len))){
      free(qdata);
      free(wsq_data);
      return(ret);
   }

   /* Store the Wavelet filter taps to the WSQ buffer. */
   if((ret = putc_transform_table(lofilt, MAX_LOFILT,
                                 hifilt, MAX_HIFILT,
                                 wsq_data, wsq_alloc, &wsq_len))){
      free(qdata);
      free(wsq_data);
      return(ret);
   }

   /* Store the quantization parameters to the WSQ buffer. */
   if((ret = putc_quantization_table(&(pwsq_data->quant_vals),
                                    wsq_data, wsq_alloc, &wsq_len))){
      free(qdata);
      free(wsq_data);
      return(ret);
   }

   /* Store a frame header to the WSQ buffer. */
   if((ret = putc_frame_header_wsq(w, h, m_shift, r_scale,
                              wsq_data, wsq_alloc, &wsq_len))){
      free(qdata);
      free(wsq_data);
      return(ret);
   }

   if(debug > 0)
      fprintf(stderr, "SOI, tables, and frame header written\n\n");

   /* Allocate a temporary buffer for holding compressed block data.    */
   /* This buffer is allocated to the size of the original input image, */
   /* and it is "assumed" that the compressed blocks will not exceed    */
   /* this buffer size.                                                 */
   huff_buf = (unsigned char *)malloc(num_pix);
   if(huff_buf == (unsigned char *)NULL) {
      free(qdata);
      free(wsq_data);
      fprintf(stderr, "ERROR : wsq_encode_1 : malloc : huff_buf\n");
      return(-13);
   }

   /******************/
   /* ENCODE Block 1 */
   /******************/
   /* Compute Huffman table for Block 1. */
   if((ret = gen_hufftable_wsq(&hufftable, &huffbits, &huffvalues,
                              qdata, &qsize1, 1))){
      free(qdata);
      free(wsq_data);
      free(huff_buf);
      return(ret);
   }

   /* Store Huffman table for Block 1 to WSQ buffer. */
   if((ret = putc_huffman_table(DHT_WSQ, 0, huffbits, huffvalues,
                               wsq_data, wsq_alloc, &wsq_len))){
      free(qdata);
      free(wsq_data);
      free(huff_buf);
      free(huffbits);
      free(huffvalues);
      free(hufftable);
      return(ret);
   }
   free(huffbits);
   free(huffvalues);

   if(debug > 0)
      fprintf(stderr, "Huffman code Table 1 generated and written\n\n");

   /* Compress Block 1 data. */
   if((ret = compress_block(huff_buf, &hsize1, qdata, qsize1,
                           MAX_HUFFCOEFF, MAX_HUFFZRUN, hufftable))){
      free(qdata);
      free(wsq_data);
      free(huff_buf);
      free(hufftable);
      return(ret);
   }
   /* Done with current Huffman table. */
   free(hufftable);

   /* Accumulate number of bytes compressed. */
   hsize = hsize1;

   /* Store Block 1's header to WSQ buffer. */
   if((ret = putc_block_header(0, wsq_data, wsq_alloc, &wsq_len))){
      free(qdata);
      free(wsq_data);
      free(huff_buf);
      return(ret);
   }

   /* Store Block 1's compressed data to WSQ buffer. */
   if((ret = putc_bytes(huff_buf, hsize1, wsq_data, wsq_alloc, &wsq_len))){
      free(qdata);
      free(wsq_data);
      free(huff_buf);
      return(ret);
   }

   if(debug > 0)
      fprintf(stderr, "Block 1 compressed and written\n\n");

   /******************/
   /* ENCODE Block 2 */
   /******************/
   /* Compute  Huffman table for Blocks 2 & 3. */
   block_sizes[0] = qsize2;
   block_sizes[1] = qsize3;
   if((ret = gen_hufftable_wsq(&hufftable, &huffbits, &huffvalues,
                          qdata+qsize1, block_sizes, 2))){
      free(qdata);
      free(wsq_data);
      free(huff_buf);
      return(ret);
   }

   /* Store Huffman table for Blocks 2 & 3 to WSQ buffer. */
   if((ret = putc_huffman_table(DHT_WSQ, 1, huffbits, huffvalues,
                               wsq_data, wsq_alloc, &wsq_len))){
      free(qdata);
      free(wsq_data);
      free(huff_buf);
      free(huffbits);
      free(huffvalues);
      free(hufftable);
      return(ret);
   }
   free(huffbits);
   free(huffvalues);

   if(debug > 0)
      fprintf(stderr, "Huffman code Table 2 generated and written\n\n");

   /* Compress Block 2 data. */
   if((ret = compress_block(huff_buf, &hsize2, qdata+qsize1, qsize2,
                           MAX_HUFFCOEFF, MAX_HUFFZRUN, hufftable))){
      free(qdata);
      free(wsq_data);
      free(huff_buf);
      free(hufftable);
      return(ret);
   }

   /* Accumulate number of bytes compressed. */
   hsize += hsize2;

   /* Store Block 2's header to WSQ buffer. */
   if((ret = putc_block_header(1, wsq_data, wsq_alloc, &wsq_len))){
      free(qdata);
      free(wsq_data);
      free(huff_buf);
      free(hufftable);
      return(ret);
   }

   /* Store Block 2's compressed data to WSQ buffer. */
   if((ret = putc_bytes(huff_buf, hsize2, wsq_data, wsq_alloc, &wsq_len))){
      free(qdata);
      free(wsq_data);
      free(huff_buf);
      free(hufftable);
      return(ret);
   }

   if(debug > 0)
      fprintf(stderr, "Block 2 compressed and written\n\n");

   /******************/
   /* ENCODE Block 3 */
   /******************/
   /* Compress Block 3 data. */
   if((ret = compress_block(huff_buf, &hsize3, qdata+qsize1+qsize2, qsize3,
                           MAX_HUFFCOEFF, MAX_HUFFZRUN, hufftable))){
      free(qdata);
      free(wsq_data);
      free(huff_buf);
      free(hufftable);
      return(ret);
   }
   /* Done with current Huffman table. */
   free(hufftable);

   /* Done with quantized image buffer. */
   free(qdata);

   /* Accumulate number of bytes compressed. */
   hsize += hsize3;

   /* Store Block 3's header to WSQ buffer. */
   if((ret = putc_block_header(1, wsq_data, wsq_alloc, &wsq_len))){
      free(wsq_data);
      free(huff_buf);
      return(ret);
   }

   /* Store Block 3's compressed data to WSQ buffer. */
   if((ret = putc_bytes(huff_buf, hsize3, wsq_data, wsq_alloc, &wsq_len))){
      free(wsq_data);
      free(huff_buf);
      return(ret);
   }

   if(debug > 0)
      fprintf(stderr, "Block 3 compressed and written\n\n");

   /* Done with huffman compressing blocks, so done with buffer. */
   free(huff_buf);

   /* Add a End Of Image (EOI) marker to the WSQ buffer. */
   if((ret = putc_ushort(EOI_WSQ, wsq_data, wsq_alloc, &wsq_len))){
      free(wsq_data);
      return(ret);
   }

   if(debug >= 1) {
      fprintf(stderr,
              "hsize1 = %d :: hsize2 = %d :: hsize3 = %d\n", hsize1, hsize2, hsize3);
      fprintf(stderr,"@ r = %.3f :: complen = %d :: ratio = %.1f\n",
              r_bitrate, hsize, (float)(num_pix)/(float)hsize);
   }

   *odata = wsq_data;
   *olen = wsq_len;

   /* Return normally. */
   return(0);
}
Example #7
0
/* ===========================================================================
 * Determine the best encoding for the current block: dynamic trees, static
 * trees or store, and output the encoded block to the zip file. This function
 * returns the total compressed length for the file so far.
 */
word32 CodeTree::flush_block(byte *buf, word32 stored_len, int eof)
{
   word32 opt_lenb, static_lenb; /* opt_len and static_len in bytes */
   int max_blindex;  /* index of last bit length code of non zero freq */

   flag_buf[last_flags] = flags; /* Save the flags for the last 8 items */

   /* Construct the literal and distance trees */
   build_tree(&l_desc);
//   Tracev((stderr, "\nlit data: dyn %ld, stat %ld", opt_len, static_len));

   build_tree(&d_desc);
//   Tracev((stderr, "\ndist data: dyn %ld, stat %ld", opt_len, static_len));
   /* At this point, opt_len and static_len are the total bit lengths of
	* the compressed block data, excluding the tree representations.
	*/

   /* Build the bit length tree for the above two trees, and get the index
	* in bl_order of the last bit length code to send.
	*/
   max_blindex = build_bl_tree();

   /* Determine the best encoding. Compute first the block length in bytes */
   opt_lenb = (opt_len+3+7)>>3;
   static_lenb = (static_len+3+7)>>3;
   input_len += stored_len; /* for debugging only */

//   Trace((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ",
//           opt_lenb, opt_len, static_lenb, static_len, stored_len,
//           last_lit, last_dist));

   if (static_lenb <= opt_lenb) opt_lenb = static_lenb;

#ifdef FORCE_METHOD
   if (level == 2 && buf) /* force stored block */
#else
   if (stored_len+4 <= opt_lenb && buf) /* 4: two words for the lengths */
#endif
   {
	   /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
		* Otherwise we can't have processed more than WSIZE input bytes since
		* the last block flush, because compression would have been
		* successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
		* transform a block into a stored block.
		*/
	   /* send block type */
	   send_bits((STORED_BLOCK<<1)+eof, 3);
	   compressed_len = (compressed_len + 3 + 7) & ~7L;
	   compressed_len += (stored_len + 4) << 3;
	   /* with header */
	   copy_block(buf, (unsigned)stored_len, 1);
   }
#ifdef FORCE_METHOD
   else if (level == 3) /* force static trees */
#else
   else if (static_lenb == opt_lenb)
#endif
   {
	   send_bits((STATIC_TREES<<1)+eof, 3);
	   compress_block(static_ltree,static_dtree);
	   compressed_len += 3 + static_len;
   } else {
	   send_bits((DYN_TREES<<1)+eof, 3);
	   send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1);
	   compress_block(dyn_ltree,dyn_dtree);
	   compressed_len += 3 + opt_len;
   }
//   assert (compressed_len == bits_sent);
   init_block();

   if (eof) {
//      assert (input_len == isize);
	  bi_windup();
	  compressed_len += 7;  /* align on byte boundary */
   }
//   Tracev((stderr,"\ncomprlen %lu(%lu) ", compressed_len>>3,
//          compressed_len-7*eof));

   return compressed_len >> 3;
}