Пример #1
0
int putc_uint(
   unsigned int iint,        /* input unsigned int       */
   unsigned char *odata,     /* output byte buffer       */
   const int oalloc,         /* allocated size of buffer */
   int *olen)                /* filled length of buffer  */
{
   int ret;
   unsigned char *cptr;

#if defined(__i386__) || defined(__x86_64__) || defined(_WIN32)
   swap_int_bytes(iint);
#endif

   cptr = (unsigned char *)(&iint);

   ret = putc_bytes(cptr, sizeof(unsigned int), odata, oalloc, olen);
   if(ret)
      return(ret);

   return(0);
}
Пример #2
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);
}