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); }
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); }