OFCondition DJCompressJP2K::encode( Uint16 columns, Uint16 rows, EP_Interpretation colorSpace, Uint16 samplesPerPixel, Uint16 * image_buffer, Uint16 * & to, Uint32 & length, Uint8 bitsAllocated, Uint8 pixelRepresentation, double minUsed, double maxUsed) { int bitsstored = bitsAllocated; if( samplesPerPixel > 1) bitsstored = bitsAllocated = 8; OFBool isSigned = pixelRepresentation; if( bitsAllocated >= 16) { int amplitude = maxUsed; if( minUsed < 0) amplitude -= minUsed; int bits = 1, value = 2; while( value < amplitude && bits <= 16) { value *= 2; bits++; } if( minUsed < 0) // K A10009536850 22.06.12 bits++; if( bits < 9) bits = 9; // avoid the artifacts... switch to lossless if( (maxUsed >= 32000 && minUsed <= -32000) || maxUsed >= 65000 || bits > 16) quality = 0; if( bits > 16) bits = 16; bitsstored = bits; } opj_cparameters_t parameters; opj_image_t *image = NULL; // printf( "JP2K OPJ-DCMTK-Encode "); opj_set_default_encoder_parameters(¶meters); parameters.tcp_numlayers = 1; parameters.cp_disto_alloc = 1; switch( quality) { case 0: // DCMLosslessQuality parameters.tcp_rates[0] = 0; break; case 1: // DCMHighQuality parameters.tcp_rates[0] = 4; break; case 2: // DCMMediumQuality if( columns <= 600 || rows <= 600) parameters.tcp_rates[0] = 6; else parameters.tcp_rates[0] = 8; break; case 3: // DCMLowQuality parameters.tcp_rates[0] = 16; break; default: //printf( "****** warning unknown compression rate -> MediumQuality : %d", quality); if( columns <= 600 || rows <= 600) parameters.tcp_rates[0] = 6; else parameters.tcp_rates[0] = 8; break; } int image_width = columns; int image_height = rows; int sample_pixel = samplesPerPixel; if (colorSpace == EPI_Monochrome1 || colorSpace == EPI_Monochrome2) { } else { if( sample_pixel != 3) printf( "*** RGB Photometric?, but... SamplesPerPixel != 3 ?"); sample_pixel = 3; } image = rawtoimage( (char *)image_buffer, ¶meters, static_cast<int>( columns*rows*samplesPerPixel*bitsAllocated/8), image_width, image_height, sample_pixel, bitsAllocated, bitsstored, isSigned, quality, 0); if(!image) { fprintf(stderr, "Unable to load buffer image\n"); return EC_Normal; } parameters.cod_format = 0; /* J2K format output */ int codestream_length; opj_codec_t *l_codec = 00; l_codec = opj_create_compress(OPJ_CODEC_J2K); opj_set_info_handler(l_codec, info_callback,00); opj_set_warning_handler(l_codec, warning_callback,00); opj_set_error_handler(l_codec, error_callback,00); /* setup the encoder parameters using the current image and using user parameters */ opj_setup_encoder(l_codec, ¶meters, image); char * l_out; size_t l_size; FILE * l_file = open_memstream(&l_out, &l_size); opj_stream_t * l_stream = opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, OPJ_FALSE); if (! l_stream){ fprintf(stderr, "failed to create stream\n"); return EC_Normal; } opj_stream_set_user_data(l_stream, l_file, (opj_stream_free_user_data_fn)NULL); opj_stream_set_write_function(l_stream, (opj_stream_write_fn)_write); /* encode the image */ int bSuccess = opj_start_compress(l_codec, image, l_stream); if (!bSuccess) { fprintf(stderr, "failed to encode image\n"); return EC_Normal; } bSuccess = bSuccess && opj_encode(l_codec, l_stream); if (!bSuccess) { opj_stream_destroy(l_stream); opj_destroy_codec(l_codec); opj_image_destroy(image); fprintf(stderr, "failed to encode image 2\n"); remove(parameters.outfile); return EC_Normal; } bSuccess = bSuccess && opj_end_compress(l_codec, l_stream); if (!bSuccess) { fprintf(stderr, "failed to encode image: opj_end_compress\n"); return EC_Normal; } /* l_file memstream must be flushed to allow accessint to l_out and l_size values */ fflush(l_file); #ifdef _WIN32 get_buffer_and_size(l_file); #endif fclose(l_file); /* copy compressed stream to "to" UINT8* */ to = new Uint16[l_size]; memcpy( to, l_out, l_size); length = l_size; /* free remaining compression structures */ free(l_out); opj_stream_destroy(l_stream); opj_destroy_codec(l_codec); opj_image_destroy(image); // } return EC_Normal; }
unsigned char * OPJSupport::compressJPEG2K(void *data, int samplesPerPixel, int rows, int columns, int bitsstored, //precision, unsigned char bitsAllocated, bool sign, int rate, long *compressedDataSize) { //enconderMutex.lock(); opj_cparameters_t parameters; opj_stream_t *l_stream = 00; opj_codec_t* l_codec = 00; opj_image_t *image = NULL; OPJ_BOOL bSuccess; OPJ_BOOL bUseTiles = OPJ_FALSE; /* OPJ_TRUE */ OPJ_UINT32 l_nb_tiles = 4; OPJ_BOOL fails = OPJ_FALSE; OPJ_CODEC_FORMAT codec_format; memset(¶meters, 0, sizeof(parameters)); opj_set_default_encoder_parameters(¶meters); parameters.outfile[0] = '\0'; parameters.tcp_numlayers = 1; parameters.cp_disto_alloc = 1; parameters.tcp_rates[0] = rate; parameters.cod_format = JP2_CFMT; //JP2_CFMT; //J2K_CFMT; OPJ_BOOL forceJ2K = (parameters.cod_format == J2K_CFMT ? OPJ_FALSE:(((OPJ_TRUE /*force here*/)))); #ifdef WITH_OPJ_FILE_STREAM tmpnam(parameters.outfile); #endif image = rawtoimage( (char*) data, ¶meters, static_cast<int>( columns*rows*samplesPerPixel*bitsAllocated/8), // [data length], fragment_size columns, rows, samplesPerPixel, bitsAllocated, bitsstored, sign, /*quality,*/ 0); if (image == NULL) { /* close and free the byte stream */ if (l_stream) opj_stream_destroy(l_stream); /* free remaining compression structures */ if (l_codec) opj_destroy_codec(l_codec); /* free image data */ if (image) opj_image_destroy(image); *compressedDataSize = 0; //enconderMutex.unlock(); return NULL; } /*-----------------------------------------------*/ switch (parameters.cod_format) { case J2K_CFMT: /* JPEG-2000 codestream */ codec_format = OPJ_CODEC_J2K; break; case JP2_CFMT: /* JPEG 2000 compressed image data */ codec_format = OPJ_CODEC_JP2; break; case JPT_CFMT: /* JPEG 2000, JPIP */ codec_format = OPJ_CODEC_JPT; break; case -1: default: fprintf(stderr,"%s:%d: encode format missing\n",__FILE__,__LINE__); /* close and free the byte stream */ if (l_stream) opj_stream_destroy(l_stream); /* free remaining compression structures */ if (l_codec) opj_destroy_codec(l_codec); /* free image data */ if (image) opj_image_destroy(image); *compressedDataSize = 0; //enconderMutex.unlock(); return NULL; } /* see test_tile_encoder.c:232 and opj_compress.c:1746 */ l_codec = opj_create_compress(codec_format); if (!l_codec) { fprintf(stderr,"%s:%d:\n\tNO codec\n",__FILE__,__LINE__); /* close and free the byte stream */ if (l_stream) opj_stream_destroy(l_stream); /* free remaining compression structures */ if (l_codec) opj_destroy_codec(l_codec); /* free image data */ if (image) opj_image_destroy(image); *compressedDataSize = 0; //enconderMutex.unlock(); return NULL; } #ifdef OPJ_VERBOSE opj_set_info_handler(l_codec, info_callback, this); opj_set_warning_handler(l_codec, warning_callback, this); #endif opj_set_error_handler(l_codec, error_callback, this); if ( !opj_setup_encoder(l_codec, ¶meters, image)) { fprintf(stderr,"%s:%d:\n\topj_setup_encoder failed\n",__FILE__,__LINE__); /* close and free the byte stream */ if (l_stream) opj_stream_destroy(l_stream); /* free remaining compression structures */ if (l_codec) opj_destroy_codec(l_codec); /* free image data */ if (image) opj_image_destroy(image); *compressedDataSize = 0; //enconderMutex.unlock(); return NULL; } // Create the stream #ifdef WITH_OPJ_BUFFER_STREAM opj_buffer_info_t bufferInfo; bufferInfo.cur = bufferInfo.buf = (OPJ_BYTE *)data; bufferInfo.len = (OPJ_SIZE_T) rows * columns; l_stream = opj_stream_create_buffer_stream(&bufferInfo, OPJ_STREAM_WRITE); //printf("%p\n",bufferInfo.buf); //printf("%lu\n",bufferInfo.len); #endif #ifdef WITH_OPJ_FILE_STREAM l_stream = opj_stream_create_default_file_stream(parameters.outfile, OPJ_STREAM_WRITE); #endif if (!l_stream) { fprintf(stderr,"%s:%d:\n\tstream creation failed\n",__FILE__,__LINE__); /* close and free the byte stream */ if (l_stream) opj_stream_destroy(l_stream); /* free remaining compression structures */ if (l_codec) opj_destroy_codec(l_codec); /* free image data */ if (image) opj_image_destroy(image); *compressedDataSize = 0; //enconderMutex.unlock(); return NULL; } while(1) { // int tile_index=-1, user_changed_tile=0, user_changed_reduction=0; // int max_tiles=0, max_reduction=0; fails = OPJ_TRUE; /* encode the image */ bSuccess = opj_start_compress(l_codec, image, l_stream); if (!bSuccess) { fprintf(stderr,"%s:%d:\n\topj_start_compress failed\n",__FILE__,__LINE__); break; } if ( bSuccess && bUseTiles ) { OPJ_BYTE *l_data = NULL; OPJ_UINT32 l_data_size = 512*512*3; //FIXME l_data = (OPJ_BYTE*) malloc(l_data_size * sizeof(OPJ_BYTE)); memset(l_data, 0, l_data_size * sizeof(OPJ_BYTE)); //assert( l_data ); if (!l_data) { /* close and free the byte stream */ if (l_stream) opj_stream_destroy(l_stream); /* free remaining compression structures */ if (l_codec) opj_destroy_codec(l_codec); /* free image data */ if (image) opj_image_destroy(image); *compressedDataSize = 0; //enconderMutex.unlock(); return NULL; } for (int i=0;i<l_nb_tiles;++i) { if (! opj_write_tile(l_codec,i,l_data,l_data_size,l_stream)) { fprintf(stderr, "\nERROR -> test_tile_encoder: failed to write the tile %d!\n",i); /* close and free the byte stream */ if (l_stream) opj_stream_destroy(l_stream); /* free remaining compression structures */ if (l_codec) opj_destroy_codec(l_codec); /* free image data */ if (image) opj_image_destroy(image); free(l_data); *compressedDataSize = 0; //enconderMutex.unlock(); return NULL; } } free(l_data); } else { if (!opj_encode(l_codec, l_stream)) { fprintf(stderr,"%s:%d:\n\topj_encode failed\n",__FILE__,__LINE__); break; } } if (!opj_end_compress(l_codec, l_stream)) { fprintf(stderr,"%s:%d:\n\topj_end_compress failed\n",__FILE__,__LINE__); break; } fails = OPJ_FALSE; break; } // while *compressedDataSize = 0; unsigned char *to = NULL; /* close and free the byte stream */ if (l_stream) opj_stream_destroy(l_stream); /* free remaining compression structures */ if (l_codec) opj_destroy_codec(l_codec); /* free image data */ if (image) opj_image_destroy(image); if (fails) { #ifdef WITH_OPJ_FILE_STREAM if (parameters.outfile[0] != '\0') remove(parameters.outfile); #endif } else { #ifdef WITH_OPJ_BUFFER_STREAM //printf("%p\n",bufferInfo.buf); //printf("%lu\n",bufferInfo.len); //to=(unsigned char *) malloc(bufferInfo.len); //memcpy(to,l_stream,bufferInfo.len); #endif #ifdef WITH_OPJ_FILE_STREAM // Open the temp file and get the encoded data into 'to' // and the length into 'length' FILE *f = NULL; if (parameters.outfile[0] != '\0') { f = fopen(parameters.outfile, "rb"); } long length = 0; if (f != NULL) { fseek(f, 0, SEEK_END); length = ftell(f); fseek(f, 0, SEEK_SET); if (forceJ2K) { length -= 85; fseek(f, 85, SEEK_SET); } if (length % 2) { length++; // ensure even length //fprintf(stdout,"Padded to %li\n", length); } to = (unsigned char *) malloc(length); fread(to, length, 1, f); //printf("%s %lu\n",parameters.outfile,length);; fclose(f); } *compressedDataSize = length; if (parameters.outfile[0] != '\0') { remove(parameters.outfile); } #endif } //enconderMutex.unlock(); return to; }