/* convert opendcp to openjpeg image format */ int odcp_to_opj(odcp_image_t *odcp, opj_image_t **opj_ptr) { OPJ_COLOR_SPACE color_space; opj_image_cmptparm_t cmptparm[3]; opj_image_t *opj = NULL; int j,size; color_space = CLRSPC_SRGB; /* initialize image components */ memset(&cmptparm[0], 0, odcp->n_components * sizeof(opj_image_cmptparm_t)); for (j = 0;j < odcp->n_components;j++) { cmptparm[j].w = odcp->w; cmptparm[j].h = odcp->h; cmptparm[j].prec = odcp->precision; cmptparm[j].bpp = odcp->bpp; cmptparm[j].sgnd = odcp->signed_bit; cmptparm[j].dx = odcp->dx; cmptparm[j].dy = odcp->dy; } /* create the image */ opj = opj_image_create(odcp->n_components, &cmptparm[0], color_space); if(!opj) { dcp_log(LOG_ERROR,"Failed to create image"); return OPENDCP_ERROR; } /* set image offset and reference grid */ opj->x0 = odcp->x0; opj->y0 = odcp->y0; opj->x1 = odcp->x1; opj->y1 = odcp->y1; size = odcp->w * odcp->h; memcpy(opj->comps[0].data,odcp->component[0].data,size*sizeof(int)); memcpy(opj->comps[1].data,odcp->component[1].data,size*sizeof(int)); memcpy(opj->comps[2].data,odcp->component[2].data,size*sizeof(int)); *opj_ptr = opj; return OPENDCP_NO_ERROR; }
static opj_image_t * gst_openjpeg_enc_fill_image (GstOpenJPEGEnc * self, GstVideoFrame * frame) { gint i, ncomps; opj_image_cmptparm_t *comps; OPJ_COLOR_SPACE colorspace; opj_image_t *image; ncomps = GST_VIDEO_FRAME_N_COMPONENTS (frame); comps = g_new0 (opj_image_cmptparm_t, ncomps); for (i = 0; i < ncomps; i++) { comps[i].prec = GST_VIDEO_FRAME_COMP_DEPTH (frame, i); comps[i].bpp = GST_VIDEO_FRAME_COMP_DEPTH (frame, i); comps[i].sgnd = 0; comps[i].w = GST_VIDEO_FRAME_COMP_WIDTH (frame, i); comps[i].h = GST_VIDEO_FRAME_COMP_HEIGHT (frame, i); comps[i].dx = GST_VIDEO_FRAME_WIDTH (frame) / GST_VIDEO_FRAME_COMP_WIDTH (frame, i); comps[i].dy = GST_VIDEO_FRAME_HEIGHT (frame) / GST_VIDEO_FRAME_COMP_HEIGHT (frame, i); } if ((frame->info.finfo->flags & GST_VIDEO_FORMAT_FLAG_YUV)) colorspace = OPJ_CLRSPC_SYCC; else if ((frame->info.finfo->flags & GST_VIDEO_FORMAT_FLAG_RGB)) colorspace = OPJ_CLRSPC_SRGB; else if ((frame->info.finfo->flags & GST_VIDEO_FORMAT_FLAG_GRAY)) colorspace = OPJ_CLRSPC_GRAY; else g_return_val_if_reached (NULL); image = opj_image_create (ncomps, comps, colorspace); g_free (comps); image->x0 = image->y0 = 0; image->x1 = GST_VIDEO_FRAME_WIDTH (frame); image->y1 = GST_VIDEO_FRAME_HEIGHT (frame); self->fill_image (image, frame); return image; }
opj_image_t * OPJ_CALLCONV mj2_image_create(mj2_tk_t * tk, opj_cparameters_t *parameters) { opj_image_cmptparm_t cmptparm[3]; opj_image_t * img; int i; int numcomps = 3; int subsampling_dx = parameters->subsampling_dx; int subsampling_dy = parameters->subsampling_dy; /* initialize image components */ memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); for(i = 0; i < numcomps; i++) { cmptparm[i].prec = tk->depth; cmptparm[i].bpp = tk->depth; cmptparm[i].sgnd = 0; cmptparm[i].dx = i ? subsampling_dx * tk->CbCr_subsampling_dx : subsampling_dx; cmptparm[i].dy = i ? subsampling_dy * tk->CbCr_subsampling_dy : subsampling_dy; cmptparm[i].w = tk->w; cmptparm[i].h = tk->h; } /* create the image */ img = opj_image_create(numcomps, cmptparm, CLRSPC_SRGB); return img; }
static int imageToPNG(const opj_image_t* image, const char* filename, int num_comp_select) { opj_image_cmptparm_t param_image_write; opj_image_t* image_write = NULL; param_image_write.x0 = 0; param_image_write.y0 = 0; param_image_write.dx = 0; param_image_write.dy = 0; param_image_write.h = image->comps[num_comp_select].h; param_image_write.w = image->comps[num_comp_select].w; param_image_write.bpp = image->comps[num_comp_select].bpp; param_image_write.prec = image->comps[num_comp_select].prec; param_image_write.sgnd = image->comps[num_comp_select].sgnd; image_write = opj_image_create(1u, ¶m_image_write, OPJ_CLRSPC_GRAY); memcpy(image_write->comps->data, image->comps[num_comp_select].data, param_image_write.h * param_image_write.w * sizeof(int)); imagetopng(image_write, filename); opj_image_destroy(image_write); return EXIT_SUCCESS; }
/******************************************************************************* * MAIN *******************************************************************************/ int main(int argc, char **argv) { test_cmp_parameters inParam; OPJ_UINT32 it_comp, itpxl; int failed = 1; int nbFilenamePGXbase = 0, nbFilenamePGXtest = 0; char *filenamePNGtest= NULL, *filenamePNGbase = NULL, *filenamePNGdiff = NULL; size_t memsizebasefilename, memsizetestfilename; size_t memsizedifffilename; int valueDiff = 0, nbPixelDiff = 0; double sumDiff = 0.0; /* Structures to store image parameters and data*/ opj_image_t *imageBase = NULL, *imageTest = NULL, *imageDiff = NULL; opj_image_cmptparm_t* param_image_diff = NULL; int decod_format; /* Get parameters from command line*/ if( parse_cmdline_cmp(argc, argv, &inParam) ) { compare_images_help_display(); goto cleanup; } /* Display Parameters*/ printf("******Parameters********* \n"); printf(" base_filename = %s\n" " test_filename = %s\n" " nb of Components = %d\n" " Non regression test = %d\n" " separator Base = %s\n" " separator Test = %s\n", inParam.base_filename, inParam.test_filename, inParam.nbcomp, inParam.nr_flag, inParam.separator_base, inParam.separator_test); if ( (inParam.tabMSEvalues != NULL) && (inParam.tabPEAKvalues != NULL)) { int it_comp2; printf(" MSE values = ["); for (it_comp2 = 0; it_comp2 < inParam.nbcomp; it_comp2++) printf(" %f ", inParam.tabMSEvalues[it_comp2]); printf("]\n"); printf(" PEAK values = ["); for (it_comp2 = 0; it_comp2 < inParam.nbcomp; it_comp2++) printf(" %f ", inParam.tabPEAKvalues[it_comp2]); printf("]\n"); printf(" Non-regression test = %d\n", inParam.nr_flag); } if (strlen(inParam.separator_base) != 0) nbFilenamePGXbase = inParam.nbcomp; if (strlen(inParam.separator_test) != 0) nbFilenamePGXtest = inParam.nbcomp; printf(" NbFilename to generate from base filename = %d\n", nbFilenamePGXbase); printf(" NbFilename to generate from test filename = %d\n", nbFilenamePGXtest); printf("************************* \n"); /*----------BASELINE IMAGE--------*/ memsizebasefilename = strlen(inParam.test_filename) + 1 + 5 + 2 + 4; memsizetestfilename = strlen(inParam.test_filename) + 1 + 5 + 2 + 4; decod_format = get_decod_format(&inParam); if( decod_format == -1 ) { fprintf( stderr, "Unhandled file format\n" ); goto cleanup; } assert( decod_format == PGX_DFMT || decod_format == TIF_DFMT || decod_format == PXM_DFMT ); if( decod_format == PGX_DFMT ) { imageBase = readImageFromFilePGX( inParam.base_filename, nbFilenamePGXbase, inParam.separator_base); if ( imageBase == NULL ) goto cleanup; } else if( decod_format == TIF_DFMT ) { imageBase = readImageFromFileTIF( inParam.base_filename, nbFilenamePGXbase, ""); if ( imageBase == NULL ) goto cleanup; } else if( decod_format == PXM_DFMT ) { imageBase = readImageFromFilePPM( inParam.base_filename, nbFilenamePGXbase, inParam.separator_base); if ( imageBase == NULL ) goto cleanup; } filenamePNGbase = (char*) malloc(memsizebasefilename); strcpy(filenamePNGbase, inParam.test_filename); strcat(filenamePNGbase, ".base"); /*printf("filenamePNGbase = %s [%d / %d octets]\n",filenamePNGbase, strlen(filenamePNGbase),memsizebasefilename );*/ /*----------TEST IMAGE--------*/ if( decod_format == PGX_DFMT ) { imageTest = readImageFromFilePGX(inParam.test_filename, nbFilenamePGXtest, inParam.separator_test); if ( imageTest == NULL ) goto cleanup; } else if( decod_format == TIF_DFMT ) { imageTest = readImageFromFileTIF(inParam.test_filename, nbFilenamePGXtest, ""); if ( imageTest == NULL ) goto cleanup; } else if( decod_format == PXM_DFMT ) { imageTest = readImageFromFilePPM(inParam.test_filename, nbFilenamePGXtest, inParam.separator_test); if ( imageTest == NULL ) goto cleanup; } filenamePNGtest = (char*) malloc(memsizetestfilename); strcpy(filenamePNGtest, inParam.test_filename); strcat(filenamePNGtest, ".test"); /*printf("filenamePNGtest = %s [%d / %d octets]\n",filenamePNGtest, strlen(filenamePNGtest),memsizetestfilename );*/ /*----------DIFF IMAGE--------*/ /* Allocate memory*/ param_image_diff = malloc( imageBase->numcomps * sizeof(opj_image_cmptparm_t)); /* Comparison of header parameters*/ printf("Step 1 -> Header comparison\n"); /* check dimensions (issue 286)*/ if(imageBase->numcomps != imageTest->numcomps ) { printf("ERROR: dim mismatch (%d><%d)\n", imageBase->numcomps, imageTest->numcomps); goto cleanup; } for (it_comp = 0; it_comp < imageBase->numcomps; it_comp++) { param_image_diff[it_comp].x0 = 0; param_image_diff[it_comp].y0 = 0; param_image_diff[it_comp].dx = 0; param_image_diff[it_comp].dy = 0; param_image_diff[it_comp].sgnd = 0; param_image_diff[it_comp].prec = 8; param_image_diff[it_comp].bpp = 1; param_image_diff[it_comp].h = imageBase->comps[it_comp].h; param_image_diff[it_comp].w = imageBase->comps[it_comp].w; if (imageBase->comps[it_comp].sgnd != imageTest->comps[it_comp].sgnd) { printf("ERROR: sign mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).sgnd, ((imageTest->comps)[it_comp]).sgnd); goto cleanup; } if (((imageBase->comps)[it_comp]).prec != ((imageTest->comps)[it_comp]).prec) { printf("ERROR: prec mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).prec, ((imageTest->comps)[it_comp]).prec); goto cleanup; } if (((imageBase->comps)[it_comp]).bpp != ((imageTest->comps)[it_comp]).bpp) { printf("ERROR: byte per pixel mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).bpp, ((imageTest->comps)[it_comp]).bpp); goto cleanup; } if (((imageBase->comps)[it_comp]).h != ((imageTest->comps)[it_comp]).h) { printf("ERROR: height mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).h, ((imageTest->comps)[it_comp]).h); goto cleanup; } if (((imageBase->comps)[it_comp]).w != ((imageTest->comps)[it_comp]).w) { printf("ERROR: width mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).w, ((imageTest->comps)[it_comp]).w); goto cleanup; } } imageDiff = opj_image_create(imageBase->numcomps, param_image_diff, OPJ_CLRSPC_UNSPECIFIED); /* Free memory*/ free(param_image_diff); param_image_diff = NULL; /* Measurement computation*/ printf("Step 2 -> measurement comparison\n"); memsizedifffilename = strlen(inParam.test_filename) + 1 + 5 + 2 + 4; filenamePNGdiff = (char*) malloc(memsizedifffilename); strcpy(filenamePNGdiff, inParam.test_filename); strcat(filenamePNGdiff, ".diff"); /*printf("filenamePNGdiff = %s [%d / %d octets]\n",filenamePNGdiff, strlen(filenamePNGdiff),memsizedifffilename );*/ /* Compute pixel diff*/ for (it_comp = 0; it_comp < imageDiff->numcomps; it_comp++) { double SE=0,PEAK=0; double MSE=0; for (itpxl = 0; itpxl < ((imageDiff->comps)[it_comp]).w * ((imageDiff->comps)[it_comp]).h; itpxl++) { if (abs( ((imageBase->comps)[it_comp]).data[itpxl] - ((imageTest->comps)[it_comp]).data[itpxl] ) > 0) { valueDiff = ((imageBase->comps)[it_comp]).data[itpxl] - ((imageTest->comps)[it_comp]).data[itpxl]; ((imageDiff->comps)[it_comp]).data[itpxl] = abs(valueDiff); sumDiff += valueDiff; nbPixelDiff++; SE += (double)valueDiff * valueDiff; PEAK = (PEAK > abs(valueDiff)) ? PEAK : abs(valueDiff); } else ((imageDiff->comps)[it_comp]).data[itpxl] = 0; }/* h*w loop */ MSE = SE / ( ((imageDiff->comps)[it_comp]).w * ((imageDiff->comps)[it_comp]).h ); if (!inParam.nr_flag && (inParam.tabMSEvalues != NULL) && (inParam.tabPEAKvalues != NULL)) { /* Conformance test*/ printf("<DartMeasurement name=\"PEAK_%d\" type=\"numeric/double\"> %f </DartMeasurement> \n", it_comp, PEAK); printf("<DartMeasurement name=\"MSE_%d\" type=\"numeric/double\"> %f </DartMeasurement> \n", it_comp, MSE); if ( (MSE > inParam.tabMSEvalues[it_comp]) || (PEAK > inParam.tabPEAKvalues[it_comp]) ) { printf("ERROR: MSE (%f) or PEAK (%f) values produced by the decoded file are greater " "than the allowable error (respectively %f and %f) \n", MSE, PEAK, inParam.tabMSEvalues[it_comp], inParam.tabPEAKvalues[it_comp]); goto cleanup; } } else /* Non regression-test */ { if ( nbPixelDiff > 0) { char it_compc[255]; it_compc[0] = 0; printf("<DartMeasurement name=\"NumberOfPixelsWithDifferences_%d\" type=\"numeric/int\"> %d </DartMeasurement> \n", it_comp, nbPixelDiff); printf("<DartMeasurement name=\"ComponentError_%d\" type=\"numeric/double\"> %f </DartMeasurement> \n", it_comp, sumDiff); #ifdef OPJ_HAVE_LIBPNG { char *filenamePNGbase_it_comp, *filenamePNGtest_it_comp, *filenamePNGdiff_it_comp; filenamePNGbase_it_comp = (char*) malloc(memsizebasefilename); strcpy(filenamePNGbase_it_comp,filenamePNGbase); filenamePNGtest_it_comp = (char*) malloc(memsizetestfilename); strcpy(filenamePNGtest_it_comp,filenamePNGtest); filenamePNGdiff_it_comp = (char*) malloc(memsizedifffilename); strcpy(filenamePNGdiff_it_comp,filenamePNGdiff); sprintf(it_compc, "_%i", it_comp); strcat(it_compc,".png"); strcat(filenamePNGbase_it_comp, it_compc); /*printf("filenamePNGbase_it = %s [%d / %d octets]\n",filenamePNGbase_it_comp, strlen(filenamePNGbase_it_comp),memsizebasefilename );*/ strcat(filenamePNGtest_it_comp, it_compc); /*printf("filenamePNGtest_it = %s [%d / %d octets]\n",filenamePNGtest_it_comp, strlen(filenamePNGtest_it_comp),memsizetestfilename );*/ strcat(filenamePNGdiff_it_comp, it_compc); /*printf("filenamePNGdiff_it = %s [%d / %d octets]\n",filenamePNGdiff_it_comp, strlen(filenamePNGdiff_it_comp),memsizedifffilename );*/ /* if ( imageToPNG(imageBase, filenamePNGbase_it_comp, it_comp) == EXIT_SUCCESS ) { printf("<DartMeasurementFile name=\"BaselineImage_%d\" type=\"image/png\"> %s </DartMeasurementFile> \n", it_comp, filenamePNGbase_it_comp); } if ( imageToPNG(imageTest, filenamePNGtest_it_comp, it_comp) == EXIT_SUCCESS ) { printf("<DartMeasurementFile name=\"TestImage_%d\" type=\"image/png\"> %s </DartMeasurementFile> \n", it_comp, filenamePNGtest_it_comp); } if ( imageToPNG(imageDiff, filenamePNGdiff_it_comp, it_comp) == EXIT_SUCCESS ) { printf("<DartMeasurementFile name=\"DiffferenceImage_%d\" type=\"image/png\"> %s </DartMeasurementFile> \n", it_comp, filenamePNGdiff_it_comp); } */ free(filenamePNGbase_it_comp); free(filenamePNGtest_it_comp); free(filenamePNGdiff_it_comp); } #endif goto cleanup; } } } /* it_comp loop */ printf("---- TEST SUCCEED ----\n"); failed = 0; cleanup: /*-----------------------------*/ free(param_image_diff); /* Free memory */ opj_image_destroy(imageBase); opj_image_destroy(imageTest); opj_image_destroy(imageDiff); free(filenamePNGbase); free(filenamePNGtest); free(filenamePNGdiff); free(inParam.tabMSEvalues); free(inParam.tabPEAKvalues); free(inParam.base_filename); free(inParam.test_filename); return failed ? EXIT_FAILURE : EXIT_SUCCESS; }
static opj_image_t* readImageFromFilePGX(const char* filename, int nbFilenamePGX, const char *separator) { int it_file; opj_image_t* image_read = NULL; opj_image_t* image = NULL; opj_cparameters_t parameters; opj_image_cmptparm_t* param_image_read; int** data; /* If separator is empty => nb file to read is equal to one*/ if ( strlen(separator) == 0 ) nbFilenamePGX = 1; /* set encoding parameters to default values */ opj_set_default_encoder_parameters(¶meters); parameters.decod_format = PGX_DFMT; strcpy(parameters.infile, filename); /* Allocate memory*/ param_image_read = malloc((size_t)nbFilenamePGX * sizeof(opj_image_cmptparm_t)); data = malloc((size_t)nbFilenamePGX * sizeof(*data)); for (it_file = 0; it_file < nbFilenamePGX; it_file++) { /* Create the right filename*/ char *filenameComponentPGX; if (strlen(separator) == 0) { filenameComponentPGX = malloc((strlen(filename) + 1) * sizeof(*filenameComponentPGX)); strcpy(filenameComponentPGX, filename); } else filenameComponentPGX = createMultiComponentsFilename(filename, it_file, separator); /* Read the pgx file corresponding to the component */ image_read = pgxtoimage(filenameComponentPGX, ¶meters); if (!image_read) { int it_free_data; fprintf(stderr, "Unable to load pgx file\n"); free(param_image_read); for (it_free_data = 0; it_free_data < it_file; it_free_data++) { free(data[it_free_data]); } free(data); free(filenameComponentPGX); return NULL; } /* Set the image_read parameters*/ param_image_read[it_file].x0 = 0; param_image_read[it_file].y0 = 0; param_image_read[it_file].dx = 0; param_image_read[it_file].dy = 0; param_image_read[it_file].h = image_read->comps->h; param_image_read[it_file].w = image_read->comps->w; param_image_read[it_file].bpp = image_read->comps->bpp; param_image_read[it_file].prec = image_read->comps->prec; param_image_read[it_file].sgnd = image_read->comps->sgnd; /* Copy data*/ data[it_file] = malloc(param_image_read[it_file].h * param_image_read[it_file].w * sizeof(int)); memcpy(data[it_file], image_read->comps->data, image_read->comps->h * image_read->comps->w * sizeof(int)); /* Free memory*/ opj_image_destroy(image_read); free(filenameComponentPGX); } image = opj_image_create((OPJ_UINT32)nbFilenamePGX, param_image_read, OPJ_CLRSPC_UNSPECIFIED); for (it_file = 0; it_file < nbFilenamePGX; it_file++) { /* Copy data into output image and free memory*/ memcpy(image->comps[it_file].data, data[it_file], image->comps[it_file].h * image->comps[it_file].w * sizeof(int)); free(data[it_file]); } /* Free memory*/ free(param_image_read); free(data); return image; }
static int j2k_encode_entry(Imaging im, ImagingCodecState state, ImagingIncrementalCodec encoder) { JPEG2KENCODESTATE *context = (JPEG2KENCODESTATE *)state->context; opj_stream_t *stream = NULL; opj_image_t *image = NULL; opj_codec_t *codec = NULL; opj_cparameters_t params; unsigned components; OPJ_COLOR_SPACE color_space; opj_image_cmptparm_t image_params[4]; unsigned xsiz, ysiz; unsigned tile_width, tile_height; unsigned tiles_x, tiles_y, num_tiles; unsigned x, y, tile_ndx; unsigned n; j2k_pack_tile_t pack; int ret = -1; stream = opj_stream_default_create(OPJ_FALSE); if (!stream) { state->errcode = IMAGING_CODEC_BROKEN; state->state = J2K_STATE_FAILED; goto quick_exit; } opj_stream_set_write_function(stream, j2k_write); opj_stream_set_skip_function(stream, j2k_skip); opj_stream_set_seek_function(stream, j2k_seek); opj_stream_set_user_data(stream, encoder); /* Setup an opj_image */ if (strcmp (im->mode, "L") == 0) { components = 1; color_space = OPJ_CLRSPC_GRAY; pack = j2k_pack_l; } else if (strcmp (im->mode, "LA") == 0) { components = 2; color_space = OPJ_CLRSPC_GRAY; pack = j2k_pack_la; } else if (strcmp (im->mode, "RGB") == 0) { components = 3; color_space = OPJ_CLRSPC_SRGB; pack = j2k_pack_rgb; } else if (strcmp (im->mode, "YCbCr") == 0) { components = 3; color_space = OPJ_CLRSPC_SYCC; pack = j2k_pack_rgb; } else if (strcmp (im->mode, "RGBA") == 0) { components = 4; color_space = OPJ_CLRSPC_SRGB; pack = j2k_pack_rgba; } else { state->errcode = IMAGING_CODEC_BROKEN; state->state = J2K_STATE_FAILED; goto quick_exit; } for (n = 0; n < components; ++n) { image_params[n].dx = image_params[n].dy = 1; image_params[n].w = im->xsize; image_params[n].h = im->ysize; image_params[n].x0 = image_params[n].y0 = 0; image_params[n].prec = 8; image_params[n].bpp = 8; image_params[n].sgnd = 0; } image = opj_image_create(components, image_params, color_space); /* Setup compression context */ context->error_msg = NULL; opj_set_default_encoder_parameters(¶ms); params.image_offset_x0 = context->offset_x; params.image_offset_y0 = context->offset_y; if (context->tile_size_x && context->tile_size_y) { params.tile_size_on = OPJ_TRUE; params.cp_tx0 = context->tile_offset_x; params.cp_ty0 = context->tile_offset_y; params.cp_tdx = context->tile_size_x; params.cp_tdy = context->tile_size_y; tile_width = params.cp_tdx; tile_height = params.cp_tdy; } else { params.cp_tx0 = 0; params.cp_ty0 = 0; params.cp_tdx = 1; params.cp_tdy = 1; tile_width = im->xsize; tile_height = im->ysize; } if (context->quality_layers && PySequence_Check(context->quality_layers)) { Py_ssize_t len = PySequence_Length(context->quality_layers); Py_ssize_t n; float *pq; if (len) { if (len > sizeof(params.tcp_rates) / sizeof(params.tcp_rates[0])) len = sizeof(params.tcp_rates)/sizeof(params.tcp_rates[0]); params.tcp_numlayers = (int)len; if (context->quality_is_in_db) { params.cp_disto_alloc = params.cp_fixed_alloc = 0; params.cp_fixed_quality = 1; pq = params.tcp_distoratio; } else { params.cp_disto_alloc = 1; params.cp_fixed_alloc = params.cp_fixed_quality = 0; pq = params.tcp_rates; } for (n = 0; n < len; ++n) { PyObject *obj = PySequence_ITEM(context->quality_layers, n); pq[n] = PyFloat_AsDouble(obj); } } } else { params.tcp_numlayers = 1; params.tcp_rates[0] = 0; params.cp_disto_alloc = 1; } if (context->num_resolutions) params.numresolution = context->num_resolutions; if (context->cblk_width >= 4 && context->cblk_width <= 1024 && context->cblk_height >= 4 && context->cblk_height <= 1024 && context->cblk_width * context->cblk_height <= 4096) { params.cblockw_init = context->cblk_width; params.cblockh_init = context->cblk_height; } if (context->precinct_width >= 4 && context->precinct_height >= 4 && context->precinct_width >= context->cblk_width && context->precinct_height > context->cblk_height) { params.prcw_init[0] = context->precinct_width; params.prch_init[0] = context->precinct_height; params.res_spec = 1; params.csty |= 0x01; } params.irreversible = context->irreversible; params.prog_order = context->progression; params.cp_cinema = context->cinema_mode; switch (params.cp_cinema) { case OPJ_OFF: params.cp_rsiz = OPJ_STD_RSIZ; break; case OPJ_CINEMA2K_24: case OPJ_CINEMA2K_48: params.cp_rsiz = OPJ_CINEMA2K; if (params.numresolution > 6) params.numresolution = 6; break; case OPJ_CINEMA4K_24: params.cp_rsiz = OPJ_CINEMA4K; if (params.numresolution > 7) params.numresolution = 7; break; } if (context->cinema_mode != OPJ_OFF) j2k_set_cinema_params(im, components, ¶ms); /* Set up the reference grid in the image */ image->x0 = params.image_offset_x0; image->y0 = params.image_offset_y0; image->x1 = xsiz = im->xsize + params.image_offset_x0; image->y1 = ysiz = im->ysize + params.image_offset_y0; /* Create the compressor */ codec = opj_create_compress(context->format); if (!codec) { state->errcode = IMAGING_CODEC_BROKEN; state->state = J2K_STATE_FAILED; goto quick_exit; } opj_set_error_handler(codec, j2k_error, context); opj_setup_encoder(codec, ¶ms, image); /* Start encoding */ if (!opj_start_compress(codec, image, stream)) { state->errcode = IMAGING_CODEC_BROKEN; state->state = J2K_STATE_FAILED; goto quick_exit; } /* Write each tile */ tiles_x = (im->xsize + (params.image_offset_x0 - params.cp_tx0) + tile_width - 1) / tile_width; tiles_y = (im->ysize + (params.image_offset_y0 - params.cp_ty0) + tile_height - 1) / tile_height; num_tiles = tiles_x * tiles_y; state->buffer = malloc (tile_width * tile_height * components); tile_ndx = 0; for (y = 0; y < tiles_y; ++y) { unsigned ty0 = params.cp_ty0 + y * tile_height; unsigned ty1 = ty0 + tile_height; unsigned pixy, pixh; if (ty0 < params.image_offset_y0) ty0 = params.image_offset_y0; if (ty1 > ysiz) ty1 = ysiz; pixy = ty0 - params.image_offset_y0; pixh = ty1 - ty0; for (x = 0; x < tiles_x; ++x) { unsigned tx0 = params.cp_tx0 + x * tile_width; unsigned tx1 = tx0 + tile_width; unsigned pixx, pixw; unsigned data_size; if (tx0 < params.image_offset_x0) tx0 = params.image_offset_x0; if (tx1 > xsiz) tx1 = xsiz; pixx = tx0 - params.image_offset_x0; pixw = tx1 - tx0; pack(im, state->buffer, pixx, pixy, pixw, pixh); data_size = pixw * pixh * components; if (!opj_write_tile(codec, tile_ndx++, state->buffer, data_size, stream)) { state->errcode = IMAGING_CODEC_BROKEN; state->state = J2K_STATE_FAILED; goto quick_exit; } } } if (!opj_end_compress(codec, stream)) { state->errcode = IMAGING_CODEC_BROKEN; state->state = J2K_STATE_FAILED; goto quick_exit; } state->errcode = IMAGING_CODEC_END; state->state = J2K_STATE_DONE; ret = (int)ImagingIncrementalCodecBytesInBuffer(encoder); quick_exit: if (codec) opj_destroy_codec(codec); if (image) opj_image_destroy(image); if (stream) opj_stream_destroy(stream); return ret; }
static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *parameters) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); opj_image_cmptparm_t *cmptparm; opj_image_t *img; int i; int sub_dx[4]; int sub_dy[4]; int numcomps; OPJ_COLOR_SPACE color_space = CLRSPC_UNKNOWN; sub_dx[0] = sub_dx[3] = 1; sub_dy[0] = sub_dy[3] = 1; sub_dx[1] = sub_dx[2] = 1 << desc->log2_chroma_w; sub_dy[1] = sub_dy[2] = 1 << desc->log2_chroma_h; numcomps = desc->nb_components; switch (avctx->pix_fmt) { case AV_PIX_FMT_GRAY8: case AV_PIX_FMT_GRAY8A: case AV_PIX_FMT_GRAY16: color_space = CLRSPC_GRAY; break; case AV_PIX_FMT_RGB24: case AV_PIX_FMT_RGBA: case AV_PIX_FMT_RGB48: case AV_PIX_FMT_RGBA64: case AV_PIX_FMT_GBR24P: case AV_PIX_FMT_GBRP9: case AV_PIX_FMT_GBRP10: case AV_PIX_FMT_GBRP12: case AV_PIX_FMT_GBRP14: case AV_PIX_FMT_GBRP16: case AV_PIX_FMT_XYZ12: color_space = CLRSPC_SRGB; break; case AV_PIX_FMT_YUV410P: case AV_PIX_FMT_YUV411P: case AV_PIX_FMT_YUV420P: case AV_PIX_FMT_YUV422P: case AV_PIX_FMT_YUV440P: case AV_PIX_FMT_YUV444P: case AV_PIX_FMT_YUVA420P: case AV_PIX_FMT_YUVA422P: case AV_PIX_FMT_YUVA444P: case AV_PIX_FMT_YUV420P9: case AV_PIX_FMT_YUV422P9: case AV_PIX_FMT_YUV444P9: case AV_PIX_FMT_YUVA420P9: case AV_PIX_FMT_YUVA422P9: case AV_PIX_FMT_YUVA444P9: case AV_PIX_FMT_YUV420P10: case AV_PIX_FMT_YUV422P10: case AV_PIX_FMT_YUV444P10: case AV_PIX_FMT_YUVA420P10: case AV_PIX_FMT_YUVA422P10: case AV_PIX_FMT_YUVA444P10: case AV_PIX_FMT_YUV420P12: case AV_PIX_FMT_YUV422P12: case AV_PIX_FMT_YUV444P12: case AV_PIX_FMT_YUV420P14: case AV_PIX_FMT_YUV422P14: case AV_PIX_FMT_YUV444P14: case AV_PIX_FMT_YUV420P16: case AV_PIX_FMT_YUV422P16: case AV_PIX_FMT_YUV444P16: case AV_PIX_FMT_YUVA420P16: case AV_PIX_FMT_YUVA422P16: case AV_PIX_FMT_YUVA444P16: color_space = CLRSPC_SYCC; break; default: av_log(avctx, AV_LOG_ERROR, "The requested pixel format '%s' is not supported\n", av_get_pix_fmt_name(avctx->pix_fmt)); return NULL; } cmptparm = av_mallocz(numcomps * sizeof(*cmptparm)); if (!cmptparm) { av_log(avctx, AV_LOG_ERROR, "Not enough memory\n"); return NULL; } for (i = 0; i < numcomps; i++) { cmptparm[i].prec = desc->comp[i].depth_minus1 + 1; cmptparm[i].bpp = desc->comp[i].depth_minus1 + 1; cmptparm[i].sgnd = 0; cmptparm[i].dx = sub_dx[i]; cmptparm[i].dy = sub_dy[i]; cmptparm[i].w = avctx->width / sub_dx[i]; cmptparm[i].h = avctx->height / sub_dy[i]; } img = opj_image_create(numcomps, cmptparm, color_space); av_freep(&cmptparm); return img; }
bool DotNetEncode(MarshalledImage* image, bool lossless) { try { opj_cparameters cparameters; opj_set_default_encoder_parameters(&cparameters); cparameters.cp_disto_alloc = 1; if (lossless) { cparameters.tcp_numlayers = 1; cparameters.tcp_rates[0] = 0; } else { cparameters.tcp_numlayers = 5; cparameters.tcp_rates[0] = 1920; cparameters.tcp_rates[1] = 480; cparameters.tcp_rates[2] = 120; cparameters.tcp_rates[3] = 30; cparameters.tcp_rates[4] = 10; cparameters.irreversible = 1; if (image->components >= 3) { cparameters.tcp_mct = 1; } } cparameters.cp_comment = (char*)""; opj_image_comptparm comptparm[5]; for (int i = 0; i < image->components; i++) { comptparm[i].bpp = 8; comptparm[i].prec = 8; comptparm[i].sgnd = 0; comptparm[i].dx = 1; comptparm[i].dy = 1; comptparm[i].x0 = 0; comptparm[i].y0 = 0; comptparm[i].w = image->width; comptparm[i].h = image->height; } opj_image_t* jp2_image = opj_image_create(image->components, comptparm, CLRSPC_SRGB); if (jp2_image == NULL) throw "opj_image_create failed"; jp2_image->x0 = 0; jp2_image->y0 = 0; jp2_image->x1 = image->width; jp2_image->y1 = image->height; int n = image->width * image->height; for (int i = 0; i < image->components; i++) std::copy(image->decoded + i * n, image->decoded + (i + 1) * n, jp2_image->comps[i].data); opj_cinfo* cinfo = opj_create_compress(CODEC_J2K); opj_setup_encoder(cinfo, &cparameters, jp2_image); opj_cio* cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0); if (cio == NULL) throw "opj_cio_open failed"; if (!opj_encode(cinfo, cio, jp2_image, cparameters.index)) return false; image->length = cio_tell(cio); image->encoded = new unsigned char[image->length]; std::copy(cio->buffer, cio->buffer + image->length, image->encoded); opj_image_destroy(jp2_image); opj_destroy_compress(cinfo); opj_cio_close(cio); return true; } catch (...) { return false; } }
static opj_image_t* upsample_image_components(opj_image_t* original) { opj_image_t* l_new_image = NULL; opj_image_cmptparm_t* l_new_components = NULL; OPJ_BOOL l_upsample_need = OPJ_FALSE; OPJ_UINT32 compno; for (compno = 0U; compno < original->numcomps; ++compno) { if (original->comps[compno].factor > 0U) { fprintf(stderr, "ERROR -> opj_decompress: -upsample not supported with reduction\n"); opj_image_destroy(original); return NULL; } if ((original->comps[compno].dx > 1U) || (original->comps[compno].dy > 1U)) { l_upsample_need = OPJ_TRUE; break; } } if (!l_upsample_need) { return original; } /* Upsample is needed */ l_new_components = (opj_image_cmptparm_t*)malloc(original->numcomps * sizeof(opj_image_cmptparm_t)); if (l_new_components == NULL) { fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for upsampled components!\n"); opj_image_destroy(original); return NULL; } for (compno = 0U; compno < original->numcomps; ++compno) { opj_image_cmptparm_t* l_new_cmp = &(l_new_components[compno]); opj_image_comp_t* l_org_cmp = &(original->comps[compno]); l_new_cmp->bpp = l_org_cmp->bpp; l_new_cmp->prec = l_org_cmp->prec; l_new_cmp->sgnd = l_org_cmp->sgnd; l_new_cmp->x0 = original->x0; l_new_cmp->y0 = original->y0; l_new_cmp->dx = 1; l_new_cmp->dy = 1; l_new_cmp->w = l_org_cmp->w; /* should be original->x1 - original->x0 for dx==1 */ l_new_cmp->h = l_org_cmp->h; /* should be original->y1 - original->y0 for dy==0 */ if (l_org_cmp->dx > 1U) { l_new_cmp->w = original->x1 - original->x0; } if (l_org_cmp->dy > 1U) { l_new_cmp->h = original->y1 - original->y0; } } l_new_image = opj_image_create(original->numcomps, l_new_components, original->color_space); free(l_new_components); if (l_new_image == NULL) { fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for upsampled components!\n"); opj_image_destroy(original); return NULL; } l_new_image->x0 = original->x0; l_new_image->x1 = original->x1; l_new_image->y0 = original->y0; l_new_image->y1 = original->y1; for (compno = 0U; compno < original->numcomps; ++compno) { opj_image_comp_t* l_new_cmp = &(l_new_image->comps[compno]); opj_image_comp_t* l_org_cmp = &(original->comps[compno]); l_new_cmp->factor = l_org_cmp->factor; l_new_cmp->alpha = l_org_cmp->alpha; l_new_cmp->resno_decoded = l_org_cmp->resno_decoded; if ((l_org_cmp->dx > 1U) || (l_org_cmp->dy > 1U)) { const OPJ_INT32* l_src = l_org_cmp->data; OPJ_INT32* l_dst = l_new_cmp->data; OPJ_UINT32 y; OPJ_UINT32 xoff, yoff; /* need to take into account dx & dy */ xoff = l_org_cmp->dx * l_org_cmp->x0 - original->x0; yoff = l_org_cmp->dy * l_org_cmp->y0 - original->y0; if ((xoff >= l_org_cmp->dx) || (yoff >= l_org_cmp->dy)) { fprintf(stderr, "ERROR -> opj_decompress: Invalid image/component parameters found when upsampling\n"); opj_image_destroy(original); opj_image_destroy(l_new_image); return NULL; } for (y = 0U; y < yoff; ++y) { memset(l_dst, 0U, l_new_cmp->w * sizeof(OPJ_INT32)); l_dst += l_new_cmp->w; } if(l_new_cmp->h > (l_org_cmp->dy - 1U)) { /* check substraction overflow for really small images */ for (; y < l_new_cmp->h - (l_org_cmp->dy - 1U); y += l_org_cmp->dy) { OPJ_UINT32 x, dy; OPJ_UINT32 xorg; xorg = 0U; for (x = 0U; x < xoff; ++x) { l_dst[x] = 0; } if (l_new_cmp->w > (l_org_cmp->dx - 1U)) { /* check substraction overflow for really small images */ for (; x < l_new_cmp->w - (l_org_cmp->dx - 1U); x += l_org_cmp->dx, ++xorg) { OPJ_UINT32 dx; for (dx = 0U; dx < l_org_cmp->dx; ++dx) { l_dst[x + dx] = l_src[xorg]; } } } for (; x < l_new_cmp->w; ++x) { l_dst[x] = l_src[xorg]; } l_dst += l_new_cmp->w; for (dy = 1U; dy < l_org_cmp->dy; ++dy) { memcpy(l_dst, l_dst - l_new_cmp->w, l_new_cmp->w * sizeof(OPJ_INT32)); l_dst += l_new_cmp->w; } l_src += l_org_cmp->w; } } if (y < l_new_cmp->h) { OPJ_UINT32 x; OPJ_UINT32 xorg; xorg = 0U; for (x = 0U; x < xoff; ++x) { l_dst[x] = 0; } if (l_new_cmp->w > (l_org_cmp->dx - 1U)) { /* check substraction overflow for really small images */ for (; x < l_new_cmp->w - (l_org_cmp->dx - 1U); x += l_org_cmp->dx, ++xorg) { OPJ_UINT32 dx; for (dx = 0U; dx < l_org_cmp->dx; ++dx) { l_dst[x + dx] = l_src[xorg]; } } } for (; x < l_new_cmp->w; ++x) { l_dst[x] = l_src[xorg]; } l_dst += l_new_cmp->w; ++y; for (; y < l_new_cmp->h; ++y) { memcpy(l_dst, l_dst - l_new_cmp->w, l_new_cmp->w * sizeof(OPJ_INT32)); l_dst += l_new_cmp->w; } } } else { memcpy(l_new_cmp->data, l_org_cmp->data, l_org_cmp->w * l_org_cmp->h * sizeof(OPJ_INT32)); } } opj_image_destroy(original); return l_new_image; }
int write_image (dt_imageio_j2k_t *j2k, const char *filename, const float *in, void *exif, int exif_len, int imgid) { opj_cparameters_t parameters; /* compression parameters */ float *rates = NULL; opj_event_mgr_t event_mgr; /* event manager */ opj_image_t *image = NULL; int quality = CLAMP(j2k->quality, 1, 100); /* configure the event callbacks (not required) setting of each callback is optionnal */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = info_callback; /* set encoding parameters to default values */ opj_set_default_encoder_parameters(¶meters); /* compression ratio */ /* invert range, from 10-100, 100-1 * where jpeg see's 1 and highest quality (lossless) and 100 is very low quality*/ parameters.tcp_rates[0] = 100 - quality + 1; parameters.tcp_numlayers = 1; /* only one resolution */ parameters.cp_disto_alloc = 1; parameters.cp_rsiz = STD_RSIZ; parameters.cod_format = j2k->format; parameters.cp_cinema = j2k->preset; if(parameters.cp_cinema) { rates = (float*)malloc(parameters.tcp_numlayers * sizeof(float)); for(int i=0; i< parameters.tcp_numlayers; i++) { rates[i] = parameters.tcp_rates[i]; } cinema_parameters(¶meters); } /* Create comment for codestream */ const char comment[] = "Created by "PACKAGE_STRING; parameters.cp_comment = g_strdup(comment); /*Converting the image to a format suitable for encoding*/ { int subsampling_dx = parameters.subsampling_dx; int subsampling_dy = parameters.subsampling_dy; int numcomps = 3; int prec = 12; //TODO: allow other bitdepths! int w = j2k->width, h = j2k->height; opj_image_cmptparm_t cmptparm[4]; /* RGBA: max. 4 components */ memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t)); for(int i = 0; i < numcomps; i++) { cmptparm[i].prec = prec; cmptparm[i].bpp = prec; cmptparm[i].sgnd = 0; cmptparm[i].dx = subsampling_dx; cmptparm[i].dy = subsampling_dy; cmptparm[i].w = w; cmptparm[i].h = h; } image = opj_image_create(numcomps, &cmptparm[0], CLRSPC_SRGB); if(!image) { fprintf(stderr, "Error: opj_image_create() failed\n"); return 1; } /* set image offset and reference grid */ image->x0 = parameters.image_offset_x0; image->y0 = parameters.image_offset_y0; image->x1 = parameters.image_offset_x0 + (w - 1) * subsampling_dx + 1; image->y1 = parameters.image_offset_y0 + (h - 1) * subsampling_dy + 1; switch(prec) { case 8: for(int i = 0; i < w * h; i++) { for(int k = 0; k < numcomps; k++) image->comps[k].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(in[i*4 + k]); } break; case 12: for(int i = 0; i < w * h; i++) { for(int k = 0; k < numcomps; k++) image->comps[k].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(in[i*4 + k]); } break; case 16: for(int i = 0; i < w * h; i++) { for(int k = 0; k < numcomps; k++) image->comps[k].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(in[i*4 + k]); } break; default: fprintf(stderr, "Error: this shouldn't happen, there is no bit depth of %d for jpeg 2000 images.\n", prec); return 1; } } /*Encoding image*/ /* Decide if MCT should be used */ parameters.tcp_mct = image->numcomps == 3 ? 1 : 0; if(parameters.cp_cinema) { cinema_setup_encoder(¶meters,image,rates); } /* encode the destination image */ /* ---------------------------- */ int rc = 1; OPJ_CODEC_FORMAT codec; if(parameters.cod_format == J2K_CFMT) /* J2K format output */ codec = CODEC_J2K; else codec = CODEC_JP2; int codestream_length; size_t res; opj_cio_t *cio = NULL; FILE *f = NULL; /* get a J2K/JP2 compressor handle */ opj_cinfo_t* cinfo = opj_create_compress(codec); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); /* setup the encoder parameters using the current image and user parameters */ opj_setup_encoder(cinfo, ¶meters, image); /* open a byte stream for writing */ /* allocate memory for all tiles */ cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0); /* encode the image */ if(!opj_encode(cinfo, cio, image, NULL)) { opj_cio_close(cio); fprintf(stderr, "failed to encode image\n"); return 1; } codestream_length = cio_tell(cio); /* write the buffer to disk */ f = fopen(filename, "wb"); if(!f) { fprintf(stderr, "failed to open %s for writing\n", filename); return 1; } res = fwrite(cio->buffer, 1, codestream_length, f); if(res < (size_t)codestream_length) /* FIXME */ { fprintf(stderr, "failed to write %d (%s)\n", codestream_length, filename); fclose(f); return 1; } fclose(f); /* close and free the byte stream */ opj_cio_close(cio); /* free remaining compression structures */ opj_destroy_compress(cinfo); /* add exif data blob. seems to not work for j2k files :( */ if(exif && j2k->format == JP2_CFMT) rc = dt_exif_write_blob(exif,exif_len,filename); /* free image data */ opj_image_destroy(image); /* free user parameters structure */ g_free(parameters.cp_comment); if(parameters.cp_matrice) free(parameters.cp_matrice); return ((rc == 1) ? 0 : 1); }
BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible) { const S32 MAX_COMPS = 5; opj_cparameters_t parameters; /* compression parameters */ opj_event_mgr_t event_mgr; /* event manager */ /* configure the event callbacks (not required) setting of each callback is optional */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = info_callback; /* set encoding parameters to default values */ opj_set_default_encoder_parameters(¶meters); parameters.cod_format = 0; parameters.cp_disto_alloc = 1; if (reversible) { parameters.tcp_numlayers = 1; parameters.tcp_rates[0] = 0.0f; } else { parameters.tcp_numlayers = 5; parameters.tcp_rates[0] = 1920.0f; parameters.tcp_rates[1] = 480.0f; parameters.tcp_rates[2] = 120.0f; parameters.tcp_rates[3] = 30.0f; parameters.tcp_rates[4] = 10.0f; parameters.irreversible = 1; if (raw_image.getComponents() >= 3) { parameters.tcp_mct = 1; } } if (!comment_text) { parameters.cp_comment = (char *) ""; } else { // Awful hacky cast, too lazy to copy right now. parameters.cp_comment = (char *) comment_text; } // // Fill in the source image from our raw image // OPJ_COLOR_SPACE color_space = CLRSPC_SRGB; opj_image_cmptparm_t cmptparm[MAX_COMPS]; opj_image_t * image = NULL; S32 numcomps = raw_image.getComponents(); S32 width = raw_image.getWidth(); S32 height = raw_image.getHeight(); memset(&cmptparm[0], 0, MAX_COMPS * sizeof(opj_image_cmptparm_t)); for(S32 c = 0; c < numcomps; c++) { cmptparm[c].prec = 8; cmptparm[c].bpp = 8; cmptparm[c].sgnd = 0; cmptparm[c].dx = parameters.subsampling_dx; cmptparm[c].dy = parameters.subsampling_dy; cmptparm[c].w = width; cmptparm[c].h = height; } /* create the image */ image = opj_image_create(numcomps, &cmptparm[0], color_space); image->x1 = width; image->y1 = height; S32 i = 0; const U8 *src_datap = raw_image.getData(); for (S32 y = height - 1; y >= 0; y--) { for (S32 x = 0; x < width; x++) { const U8 *pixel = src_datap + (y*width + x) * numcomps; for (S32 c = 0; c < numcomps; c++) { image->comps[c].data[i] = *pixel; pixel++; } i++; } } /* encode the destination image */ /* ---------------------------- */ int codestream_length; opj_cio_t *cio = NULL; /* get a J2K compressor handle */ opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); /* setup the encoder parameters using the current image and using user parameters */ opj_setup_encoder(cinfo, ¶meters, image); /* open a byte stream for writing */ /* allocate memory for all tiles */ cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0); /* encode the image */ bool bSuccess = opj_encode(cinfo, cio, image, NULL); if (!bSuccess) { opj_cio_close(cio); LL_DEBUGS("Texture") << "Failed to encode image." << LL_ENDL; return FALSE; } codestream_length = cio_tell(cio); base.copyData(cio->buffer, codestream_length); base.updateData(); // set width, height /* close and free the byte stream */ opj_cio_close(cio); /* free remaining compression structures */ opj_destroy_compress(cinfo); /* free user parameters structure */ if(parameters.cp_matrice) free(parameters.cp_matrice); /* free image data */ opj_image_destroy(image); return TRUE; }
/* Add a frame to the end of an IPX file */ int IPX_write_frame(TFrame *frame, IPX_status *status) { opj_image_t *image = NULL; uint codestream_length, datasize; opj_cio_t *cio = NULL; opj_image_cmptparm_t cmptparm; int i, j, p; float factor; static int jp2_init = 1; static opj_event_mgr_t event_mgr; /* event manager */ static opj_cparameters_t parameters; /* compression parameters */ static opj_cinfo_t* cinfo; if((status->header.height == 0) || (status->header.width == 0)) { /* Width and height not set yet */ status->header.height = frame->height; status->header.width = frame->width; } if((status->header.height != frame->height) || (status->header.width != frame->width)) { /* Frame is wrong size */ return(IO_ERROR_SIZE); } if(jp2_init) { jp2_init = 0; /* Setup callbacks */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = info_callback; /* Set default compression parameters */ opj_set_default_encoder_parameters(¶meters); /* Get a compressor handle */ cinfo = opj_create_compress(CODEC_JP2); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); } /* Create an image structure */ memset(&cmptparm, 0, sizeof(opj_image_cmptparm_t)); /* Set image parameters */ cmptparm.prec = status->header.depth; cmptparm.bpp = cmptparm.prec; cmptparm.sgnd = 0; cmptparm.dx = parameters.subsampling_dx; cmptparm.dy = parameters.subsampling_dy; cmptparm.w = frame->width; cmptparm.h = frame->height; /* Create image */ image = opj_image_create(1, &cmptparm, CLRSPC_GRAY); if(!image) { printf("Error: Cannot create image\n"); exit(0); } /* set image offset and reference grid */ image->x0 = parameters.image_offset_x0; image->y0 = parameters.image_offset_y0; image->x1 = parameters.image_offset_x0 + (cmptparm.w - 1) * parameters.subsampling_dx + 1; image->y1 = parameters.image_offset_y0 + (cmptparm.h - 1) * parameters.subsampling_dy + 1; factor = (float) ((1 << cmptparm.prec) - 1); p = 0; for(j=0;j<status->header.height;j++) { for(i=0;i<status->header.width;i++) { image->comps[0].data[p] = (int) (factor * frame->data[i][j]); p++; } } image->comps[0].bpp = cmptparm.bpp; /* if no rate entered, lossless by default */ if(parameters.tcp_numlayers == 0) { parameters.tcp_rates[0] = 0; parameters.tcp_numlayers++; parameters.cp_disto_alloc = 1; } /* setup the encoder parameters using the current image and using user parameters */ opj_setup_encoder(cinfo, ¶meters, image); /* open a byte stream for writing */ /* allocate memory for all tiles */ if((cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0)) == NULL) { printf("Error: could not open CIO buffer\n"); exit(0); } /* encode the image */ if(!opj_encode(cinfo, cio, image, NULL)) { opj_cio_close(cio); return(IO_ERROR_OTHER); } /* Length of JP2 code stream */ codestream_length = cio_tell(cio); /* Length of header + JP2 data */ datasize = codestream_length + IPX_UINT + IPX_DOUBLE; //sizeof(uint) + sizeof(double); /* printf("Writing frame %d at position %ld, size %d\n", status->header.numFrames, ftell(status->fd), codestream_length); */ /* Write frame header */ //printf("Writing header: %ld, %d ->", ftell(status->fd), sizeof(uint)+sizeof(double)); fwrite(&datasize, IPX_UINT, 1, status->fd); fwrite(&(frame->time), IPX_DOUBLE, 1, status->fd); //printf(" %ld\n", ftell(status->fd)); /* write the frame data */ fwrite(cio->buffer, 1, codestream_length, status->fd); /* Update header */ status->header.numFrames++; /* Free memory */ opj_cio_close(cio); opj_image_destroy(image); return(0); }
int main(int argc, char *argv[]) { const char * v = opj_version(); const OPJ_COLOR_SPACE color_space = OPJ_CLRSPC_GRAY; unsigned int numcomps = 1; unsigned int i; unsigned int image_width = 256; unsigned int image_height = 256; opj_cparameters_t parameters; unsigned int subsampling_dx; unsigned int subsampling_dy; const char outputfile[] = "testempty2.j2k"; opj_image_cmptparm_t cmptparm; opj_image_t *image; opj_codec_t* l_codec = 00; OPJ_BOOL bSuccess; opj_stream_t *l_stream = 00; (void)argc; (void)argv; opj_set_default_encoder_parameters(¶meters); parameters.cod_format = J2K_CFMT; puts(v); subsampling_dx = (unsigned int)parameters.subsampling_dx; subsampling_dy = (unsigned int)parameters.subsampling_dy; cmptparm.prec = 8; cmptparm.bpp = 8; cmptparm.sgnd = 0; cmptparm.dx = subsampling_dx; cmptparm.dy = subsampling_dy; cmptparm.w = image_width; cmptparm.h = image_height; strncpy(parameters.outfile, outputfile, sizeof(parameters.outfile)-1); image = opj_image_create(numcomps, &cmptparm, color_space); assert( image ); for (i = 0; i < image_width * image_height; i++) { unsigned int compno; for(compno = 0; compno < numcomps; compno++) { image->comps[compno].data[i] = 0; } } /* catch events using our callbacks and give a local context */ 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); 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); opj_setup_encoder(l_codec, ¶meters, image); l_stream = opj_stream_create_default_file_stream_v3(parameters.outfile,OPJ_FALSE); if( !l_stream ) { fprintf( stderr, "Something went wrong during creation of stream\n" ); opj_destroy_codec(l_codec); opj_image_destroy(image); opj_stream_destroy_v3(l_stream); return 1; } assert(l_stream); bSuccess = opj_start_compress(l_codec,image,l_stream); if( !bSuccess ) { opj_stream_destroy_v3(l_stream); opj_destroy_codec(l_codec); opj_image_destroy(image); return 0; } assert( bSuccess ); bSuccess = opj_encode(l_codec, l_stream); assert( bSuccess ); bSuccess = opj_end_compress(l_codec, l_stream); assert( bSuccess ); opj_stream_destroy_v3(l_stream); opj_destroy_codec(l_codec); opj_image_destroy(image); /* read back the generated file */ { opj_codec_t* d_codec = 00; opj_dparameters_t dparameters; d_codec = opj_create_decompress(OPJ_CODEC_J2K); opj_set_info_handler(d_codec, info_callback,00); opj_set_warning_handler(d_codec, warning_callback,00); opj_set_error_handler(d_codec, error_callback,00); bSuccess = opj_setup_decoder(d_codec, &dparameters); assert( bSuccess ); l_stream = opj_stream_create_default_file_stream_v3(outputfile,1); assert( l_stream ); bSuccess = opj_read_header(l_stream, d_codec, &image); assert( bSuccess ); bSuccess = opj_decode(l_codec, l_stream, image); assert( bSuccess ); bSuccess = opj_end_decompress(l_codec, l_stream); assert( bSuccess ); opj_stream_destroy_v3(l_stream); opj_destroy_codec(d_codec); opj_image_destroy(image); } puts( "end" ); return 0; }
BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible) { const S32 MAX_COMPS = 5; opj_cparameters_t parameters; /* compression parameters */ opj_event_mgr_t event_mgr; /* event manager */ /* configure the event callbacks (not required) setting of each callback is optional */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = info_callback; /* set encoding parameters to default values */ opj_set_default_encoder_parameters(¶meters); parameters.cod_format = 0; parameters.cp_disto_alloc = 1; if (reversible) { parameters.tcp_numlayers = 1; parameters.tcp_rates[0] = 0.0f; } else { parameters.tcp_numlayers = 5; parameters.tcp_rates[0] = 1920.0f; parameters.tcp_rates[1] = 480.0f; parameters.tcp_rates[2] = 120.0f; parameters.tcp_rates[3] = 30.0f; parameters.tcp_rates[4] = 10.0f; parameters.irreversible = 1; if (raw_image.getComponents() >= 3) { parameters.tcp_mct = 1; } } std::string comment_metadata; if (!comment_text) { //Inserting owner id, upload time, and dimensions //See http://wiki.secondlife.com/wiki/Texture_meta-data for details. extern LLUUID gAgentID; time_t now = time(NULL); tm * ptime = gmtime(&now); //std::string color_avg(llformat("c=%02x%02x%02x%02x")); //Perhaps do this some day... std::string timestr(llformat("z=%04i%02i%02i%02i%02i%02i",ptime->tm_year+1900,ptime->tm_mon+1,ptime->tm_mday,ptime->tm_hour,ptime->tm_min,ptime->tm_sec)); comment_metadata=llformat("a=%s&%s&h=%u&w=%u",gAgentID.asString().c_str(),timestr.c_str(),(U32)raw_image.getHeight(),(U32)raw_image.getWidth()); parameters.cp_comment = (char *) comment_metadata.c_str(); } else { // Awful hacky cast, too lazy to copy right now. parameters.cp_comment = (char *) comment_text; } // // Fill in the source image from our raw image // OPJ_COLOR_SPACE color_space = CLRSPC_SRGB; opj_image_cmptparm_t cmptparm[MAX_COMPS]; opj_image_t * image = NULL; S32 numcomps = llmin((S32)raw_image.getComponents(),(S32)MAX_COMPS); //Clamp avoid overrunning buffer -Shyotl S32 width = raw_image.getWidth(); S32 height = raw_image.getHeight(); memset(&cmptparm[0], 0, MAX_COMPS * sizeof(opj_image_cmptparm_t)); for(S32 c = 0; c < numcomps; c++) { cmptparm[c].prec = 8; cmptparm[c].bpp = 8; cmptparm[c].sgnd = 0; cmptparm[c].dx = parameters.subsampling_dx; cmptparm[c].dy = parameters.subsampling_dy; cmptparm[c].w = width; cmptparm[c].h = height; } /* create the image */ image = opj_image_create(numcomps, &cmptparm[0], color_space); image->x1 = width; image->y1 = height; S32 i = 0; const U8 *src_datap = raw_image.getData(); for (S32 y = height - 1; y >= 0; y--) { for (S32 x = 0; x < width; x++) { const U8 *pixel = src_datap + (y*width + x) * numcomps; for (S32 c = 0; c < numcomps; c++) { image->comps[c].data[i] = *pixel; pixel++; } i++; } } /* encode the destination image */ /* ---------------------------- */ int codestream_length; opj_cio_t *cio = NULL; /* get a J2K compressor handle */ opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); /* setup the encoder parameters using the current image and using user parameters */ opj_setup_encoder(cinfo, ¶meters, image); /* open a byte stream for writing */ /* allocate memory for all tiles */ cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0); /* encode the image */ bool bSuccess = opj_encode(cinfo, cio, image, NULL); if (!bSuccess) { opj_cio_close(cio); llinfos << "Failed to encode image." << llendl; return FALSE; } codestream_length = cio_tell(cio); base.copyData(cio->buffer, codestream_length); base.updateData(); // set width, height /* close and free the byte stream */ opj_cio_close(cio); /* free remaining compression structures */ opj_destroy_compress(cinfo); /* free user parameters structure */ if(parameters.cp_matrice) free(parameters.cp_matrice); /* free image data */ opj_image_destroy(image); return TRUE; }
opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params) { png_structp png = NULL; png_infop info = NULL; double gamma; int bit_depth, interlace_type,compression_type, filter_type; uint32_t i; png_uint_32 width, height = 0U; int color_type; FILE *reader = NULL; uint8_t** rows = NULL; int32_t* row32s = NULL; /* j2k: */ opj_image_t *image = NULL; opj_image_cmptparm_t cmptparm[4]; uint32_t nr_comp; uint8_t sigbuf[8]; convert_XXx32s_C1R cvtXXTo32s = NULL; convert_32s_CXPX cvtCxToPx = NULL; int32_t* planes[4]; if((reader = fopen(read_idf, "rb")) == NULL) { fprintf(stderr,"pngtoimage: can not open %s\n",read_idf); return NULL; } if(fread(sigbuf, 1, MAGIC_SIZE, reader) != MAGIC_SIZE || memcmp(sigbuf, PNG_MAGIC, MAGIC_SIZE) != 0) { fprintf(stderr,"pngtoimage: %s is no valid PNG file\n",read_idf); goto fin; } if((png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL) goto fin; if((info = png_create_info_struct(png)) == NULL) goto fin; if(setjmp(png_jmpbuf(png))) goto fin; png_init_io(png, reader); png_set_sig_bytes(png, MAGIC_SIZE); png_read_info(png, info); if(png_get_IHDR(png, info, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_type) == 0) goto fin; /* png_set_expand(): * expand paletted images to RGB, expand grayscale images of * less than 8-bit depth to 8-bit depth, and expand tRNS chunks * to alpha channels. */ if(color_type == PNG_COLOR_TYPE_PALETTE) { png_set_expand(png); } if(png_get_valid(png, info, PNG_INFO_tRNS)) { png_set_expand(png); } /* We might wan't to expand background */ /* if(png_get_valid(png, info, PNG_INFO_bKGD)) { png_color_16p bgnd; png_get_bKGD(png, info, &bgnd); png_set_background(png, bgnd, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); } */ if( !png_get_gAMA(png, info, &gamma)) gamma = 1.0; /* we're not displaying but converting, screen gamma == 1.0 */ png_set_gamma(png, 1.0, gamma); png_read_update_info(png, info); color_type = png_get_color_type(png, info); switch (color_type) { case PNG_COLOR_TYPE_GRAY: nr_comp = 1; break; case PNG_COLOR_TYPE_GRAY_ALPHA: nr_comp = 2; break; case PNG_COLOR_TYPE_RGB: nr_comp = 3; break; case PNG_COLOR_TYPE_RGB_ALPHA: nr_comp = 4; break; default: fprintf(stderr,"pngtoimage: colortype %d is not supported\n", color_type); goto fin; } cvtCxToPx = convert_32s_CXPX_LUT[nr_comp]; bit_depth = png_get_bit_depth(png, info); switch (bit_depth) { case 1: case 2: case 4: case 8: cvtXXTo32s = convert_XXu32s_C1R_LUT[bit_depth]; break; case 16: /* 16 bpp is specific to PNG */ cvtXXTo32s = convert_16u32s_C1R; break; default: fprintf(stderr,"pngtoimage: bit depth %d is not supported\n", bit_depth); goto fin; } rows = (uint8_t**)calloc(height+1, sizeof(uint8_t*)); if (rows == NULL) { fprintf(stderr, "pngtoimage: out of memory\n"); goto fin; } for (i = 0; i < height; ++i) { rows[i] = (uint8_t*)malloc(png_get_rowbytes(png, info)); if (!rows[i]) { fprintf(stderr, "pngtoimage: out of memory\n"); goto fin; } } png_read_image(png, rows); /* Create image */ memset(cmptparm, 0, sizeof(cmptparm)); for(i = 0; i < nr_comp; ++i) { cmptparm[i].prec = bit_depth; cmptparm[i].sgnd = 0; cmptparm[i].dx = params->subsampling_dx; cmptparm[i].dy = params->subsampling_dy; cmptparm[i].w = width; cmptparm[i].h = height; } image = opj_image_create(nr_comp, &cmptparm[0], (nr_comp > 2U) ? OPJ_CLRSPC_SRGB : OPJ_CLRSPC_GRAY); if(image == NULL) goto fin; image->x0 = params->image_offset_x0; image->y0 = params->image_offset_y0; image->x1 = (image->x0 + (width - 1) * params->subsampling_dx + 1 + image->x0); image->y1 = (image->y0 + (height - 1) * params->subsampling_dy + 1 + image->y0); row32s = (int32_t *)malloc((size_t)width * nr_comp * sizeof(int32_t)); if(row32s == NULL) goto fin; /* Set alpha channel */ image->comps[nr_comp-1U].alpha = 1U - (nr_comp & 1U); for(i = 0; i < nr_comp; i++) { planes[i] = image->comps[i].data; } for(i = 0; i < height; ++i) { cvtXXTo32s(rows[i], row32s, (size_t)width * nr_comp); cvtCxToPx(row32s, planes, width); planes[0] += width; planes[1] += width; planes[2] += width; planes[3] += width; } fin: if(rows) { for (i = 0; i < height; ++i) { if (rows[i]) free(rows[i]); } free(rows); } if (row32s) { free(row32s); } if(png) png_destroy_read_struct(&png, &info, NULL); fclose(reader); return image; }/* pngtoimage() */
static opj_image_t* ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) { unsigned char *rect; float *rect_float; int subsampling_dx = parameters->subsampling_dx; int subsampling_dy = parameters->subsampling_dy; int i, numcomps, w, h, prec; int x,y, y_row; OPJ_COLOR_SPACE color_space; opj_image_cmptparm_t cmptparm[4]; /* maximum of 4 components */ opj_image_t * image = NULL; img_fol_t img_fol; /* only needed for cinema presets */ memset(&img_fol,0,sizeof(img_fol_t)); if (ibuf->ftype & JP2_CINE) { if (ibuf->x==4096 || ibuf->y==2160) parameters->cp_cinema= CINEMA4K_24; else { if (ibuf->ftype & JP2_CINE_48FPS) { parameters->cp_cinema= CINEMA2K_48; } else { parameters->cp_cinema= CINEMA2K_24; } } if (parameters->cp_cinema){ img_fol.rates = (float*)MEM_mallocN(parameters->tcp_numlayers * sizeof(float), "jp2_rates"); for(i=0; i< parameters->tcp_numlayers; i++){ img_fol.rates[i] = parameters->tcp_rates[i]; } cinema_parameters(parameters); } color_space= CLRSPC_SYCC; prec= 12; numcomps= 3; } else { /* Get settings from the imbuf */ color_space = (ibuf->ftype & JP2_YCC) ? CLRSPC_SYCC : CLRSPC_SRGB; if (ibuf->ftype & JP2_16BIT) prec= 16; else if (ibuf->ftype & JP2_12BIT) prec= 12; else prec= 8; /* 32bit images == alpha channel */ /* grayscale not supported yet */ numcomps= (ibuf->depth==32) ? 4 : 3; } w= ibuf->x; h= ibuf->y; /* initialize image components */ memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t)); for(i = 0; i < numcomps; i++) { cmptparm[i].prec = prec; cmptparm[i].bpp = prec; cmptparm[i].sgnd = 0; cmptparm[i].dx = subsampling_dx; cmptparm[i].dy = subsampling_dy; cmptparm[i].w = w; cmptparm[i].h = h; } /* create the image */ image = opj_image_create(numcomps, &cmptparm[0], color_space); if(!image) { printf("Error: opj_image_create() failed\n"); return NULL; } /* set image offset and reference grid */ image->x0 = parameters->image_offset_x0; image->y0 = parameters->image_offset_y0; image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1; image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1; /* set image data */ rect = (unsigned char*) ibuf->rect; rect_float= ibuf->rect_float; if (rect_float && rect && prec==8) { /* No need to use the floating point buffer, just write the 8 bits from the char buffer */ rect_float= NULL; } if (rect_float) { float rgb[3]; switch (prec) { case 8: /* Convert blenders float color channels to 8,12 or 16bit ints */ for(y=h-1; y>=0; y--) { y_row = y*w; for(x=0; x<w; x++, rect_float+=4) { i = y_row + x; if (ibuf->profile == IB_PROFILE_LINEAR_RGB) linearrgb_to_srgb_v3_v3(rgb, rect_float); else copy_v3_v3(rgb, rect_float); image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[0]); image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[1]); image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rgb[2]); if (numcomps>3) image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_8BIT(rect_float[3]); } } break; case 12: for(y=h-1; y>=0; y--) { y_row = y*w; for(x=0; x<w; x++, rect_float+=4) { i = y_row + x; if (ibuf->profile == IB_PROFILE_LINEAR_RGB) linearrgb_to_srgb_v3_v3(rgb, rect_float); else copy_v3_v3(rgb, rect_float); image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[0]); image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[1]); image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rgb[2]); if (numcomps>3) image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_12BIT(rect_float[3]); } } break; case 16: for(y=h-1; y>=0; y--) { y_row = y*w; for(x=0; x<w; x++, rect_float+=4) { i = y_row + x; if (ibuf->profile == IB_PROFILE_LINEAR_RGB) linearrgb_to_srgb_v3_v3(rgb, rect_float); else copy_v3_v3(rgb, rect_float); image->comps[0].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[0]); image->comps[1].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[1]); image->comps[2].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rgb[2]); if (numcomps>3) image->comps[3].data[i] = DOWNSAMPLE_FLOAT_TO_16BIT(rect_float[3]); } } break; } } else { /* just use rect*/ switch (prec) { case 8: for(y=h-1; y>=0; y--) { y_row = y*w; for(x=0; x<w; x++, rect+=4) { i = y_row + x; image->comps[0].data[i] = rect[0]; image->comps[1].data[i] = rect[1]; image->comps[2].data[i] = rect[2]; if (numcomps>3) image->comps[3].data[i] = rect[3]; } } break; case 12: /* Up Sampling, a bit pointless but best write the bit depth requested */ for(y=h-1; y>=0; y--) { y_row = y*w; for(x=0; x<w; x++, rect+=4) { i = y_row + x; image->comps[0].data[i]= UPSAMPLE_8_TO_12(rect[0]); image->comps[1].data[i]= UPSAMPLE_8_TO_12(rect[1]); image->comps[2].data[i]= UPSAMPLE_8_TO_12(rect[2]); if (numcomps>3) image->comps[3].data[i]= UPSAMPLE_8_TO_12(rect[3]); } } break; case 16: for(y=h-1; y>=0; y--) { y_row = y*w; for(x=0; x<w; x++, rect+=4) { i = y_row + x; image->comps[0].data[i]= UPSAMPLE_8_TO_16(rect[0]); image->comps[1].data[i]= UPSAMPLE_8_TO_16(rect[1]); image->comps[2].data[i]= UPSAMPLE_8_TO_16(rect[2]); if (numcomps>3) image->comps[3].data[i]= UPSAMPLE_8_TO_16(rect[3]); } } break; } } /* Decide if MCT should be used */ parameters->tcp_mct = image->numcomps == 3 ? 1 : 0; if(parameters->cp_cinema){ cinema_setup_encoder(parameters,image,&img_fol); } if (img_fol.rates) MEM_freeN(img_fol.rates); return image; }
static opj_image_t * rawtoimage(char *inputbuffer, opj_cparameters_t *parameters, int fragment_size, int image_width, int image_height, int sample_pixel, int bitsallocated, int bitsstored, int sign, int quality, int pc){ (void)quality; (void)fragment_size; int w, h; int numcomps; OPJ_COLOR_SPACE color_space; opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */ opj_image_t * image = NULL; assert( sample_pixel == 1 || sample_pixel == 3 ); if( sample_pixel == 1 ) { numcomps = 1; color_space = OPJ_CLRSPC_GRAY; } else // sample_pixel == 3 { numcomps = 3; color_space = OPJ_CLRSPC_SRGB; /* Does OpenJPEg support: CLRSPC_SYCC ?? */ } if( bitsallocated % 8 != 0 ) { fprintf( stderr, "BitsAllocated is not 8\n" ); return 0; } assert( bitsallocated % 8 == 0 ); // eg. fragment_size == 63532 and 181 * 117 * 3 * 8 == 63531 ... assert( ((fragment_size + 1)/2 ) * 2 == ((image_height * image_width * numcomps * (bitsallocated/8) + 1)/ 2 )* 2 ); int subsampling_dx = parameters->subsampling_dx; int subsampling_dy = parameters->subsampling_dy; // FIXME w = image_width; h = image_height; /* initialize image components */ memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); //assert( bitsallocated == 8 ); for(int i = 0; i < numcomps; i++) { cmptparm[i].prec = bitsstored; cmptparm[i].bpp = bitsallocated; cmptparm[i].sgnd = sign; cmptparm[i].dx = subsampling_dx; cmptparm[i].dy = subsampling_dy; cmptparm[i].w = w; cmptparm[i].h = h; } /* create the image */ image = opj_image_create(numcomps, &cmptparm[0], color_space); if(!image) { return NULL; } /* set image offset and reference grid */ image->x0 = parameters->image_offset_x0; image->y0 = parameters->image_offset_y0; image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1; image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1; /* set image data */ //assert( fragment_size == numcomps*w*h*(bitsallocated/8) ); if (bitsallocated <= 8) { if( sign ) { rawtoimage_fill<int8_t>((int8_t*)inputbuffer,w,h,numcomps,image,pc); } else { rawtoimage_fill<uint8_t>((uint8_t*)inputbuffer,w,h,numcomps,image,pc); } } else if (bitsallocated <= 16) { if( sign ) { rawtoimage_fill<int16_t>((int16_t*)inputbuffer,w,h,numcomps,image,pc); } else { rawtoimage_fill<uint16_t>((uint16_t*)inputbuffer,w,h,numcomps,image,pc); } } else if (bitsallocated <= 32) { if( sign ) { rawtoimage_fill<int32_t>((int32_t*)inputbuffer,w,h,numcomps,image,pc); } else { rawtoimage_fill<uint32_t>((uint32_t*)inputbuffer,w,h,numcomps,image,pc); } } else { return NULL; } return image; }
char* J2kConverter::encode(int16_t* data, unsigned int imageWidth, unsigned int imageHeight, size_t& outSize, float distoRatio) { opj_cparameters_t params; opj_image_cmptparm_t compParams; opj_set_default_encoder_parameters(¶ms); params.tcp_numlayers = 1; params.cp_fixed_quality = 1; params.tcp_distoratio[0] = distoRatio; params.cp_tx0 = 0; params.cp_ty0 = 0; params.tile_size_on = OPJ_FALSE; params.irreversible = true; params.numresolution = 1; params.prog_order = OPJ_LRCP; compParams.w = imageWidth; compParams.h = imageHeight; compParams.sgnd = 0; compParams.prec = 16; compParams.bpp = 16; compParams.x0 = 0; compParams.y0 = 0; compParams.dx = 1; compParams.dy = 1; opj_codec_t *codec = opj_create_compress(OPJ_CODEC_J2K); opj_set_info_handler(codec, infoCallback, nullptr); opj_set_warning_handler(codec, warningCallback, nullptr); opj_set_error_handler(codec, errorCallback, nullptr); opj_image_t *image = opj_image_create(1, &compParams, OPJ_CLRSPC_GRAY); if (!image) { opj_destroy_codec(codec); return nullptr; } unsigned int nPixels = imageWidth * imageHeight; for (unsigned int i = 0; i < nPixels; ++i) { image->comps[0].data[i] = data[i]; } image->x0 = 0; image->y0 = 0; image->x1 = static_cast<OPJ_UINT32>(imageWidth); image->y1 = static_cast<OPJ_UINT32>(imageHeight); image->color_space = OPJ_CLRSPC_GRAY; if (!opj_setup_encoder(codec, ¶ms, image)) { std::cout << "Could not set up encoder." << std::endl; opj_destroy_codec(codec); opj_image_destroy(image); return nullptr; } MemoryStream* ms = new MemoryStream; opj_stream_t *stream = createOpjMemoryStream(OPJ_FALSE, ms); if (!stream) { std::cout << "Could not set up stream" << std::endl; opj_destroy_codec(codec); opj_image_destroy(image); return nullptr; } if (!opj_start_compress(codec, image, stream)) { std::cout << "Could not start compression." << std::endl; opj_stream_destroy(stream); opj_destroy_codec(codec); opj_image_destroy(image); return nullptr; } if (!opj_encode(codec, stream)) { std::cout << "Could not encode data." << std::endl; opj_stream_destroy(stream); opj_destroy_codec(codec); opj_image_destroy(image); return nullptr; } if (!opj_end_compress(codec, stream)) { std::cout << "Could not end compression." << std::endl; opj_stream_destroy(stream); opj_destroy_codec(codec); opj_image_destroy(image); return nullptr; } outSize = ms->data.size(); char* outData = new char[outSize]; memcpy(outData, ms->data.data(), outSize); opj_stream_destroy(stream); opj_destroy_codec(codec); opj_image_destroy(image); delete ms; return outData; }
opj_image_t* bmptoimage(char *filename, opj_cparameters_t *parameters) { int subsampling_dx = parameters->subsampling_dx; int subsampling_dy = parameters->subsampling_dy; int i, numcomps, w, h; OPJ_COLOR_SPACE color_space; opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */ opj_image_t * image = NULL; FILE *IN; BITMAPFILEHEADER_t File_h; BITMAPINFOHEADER_t Info_h; unsigned char *RGB; unsigned char *table_R, *table_G, *table_B; unsigned int j, PAD = 0; int x, y, index; int gray_scale = 1, not_end_file = 1; unsigned int line = 0, col = 0; unsigned char v, v2; DWORD W, H; IN = fopen(filename, "rb"); if (!IN) { fprintf(stderr, "\033[0;33mFailed to open %s for reading !!\033[0;39m\n", filename); return 0; } File_h.bfType = getc(IN); File_h.bfType = (getc(IN) << 8) + File_h.bfType; if (File_h.bfType != 19778) { fprintf(stderr,"Error, not a BMP file!\n"); return 0; } else { /* FILE HEADER */ /* ------------- */ File_h.bfSize = getc(IN); File_h.bfSize = (getc(IN) << 8) + File_h.bfSize; File_h.bfSize = (getc(IN) << 16) + File_h.bfSize; File_h.bfSize = (getc(IN) << 24) + File_h.bfSize; File_h.bfReserved1 = getc(IN); File_h.bfReserved1 = (getc(IN) << 8) + File_h.bfReserved1; File_h.bfReserved2 = getc(IN); File_h.bfReserved2 = (getc(IN) << 8) + File_h.bfReserved2; File_h.bfOffBits = getc(IN); File_h.bfOffBits = (getc(IN) << 8) + File_h.bfOffBits; File_h.bfOffBits = (getc(IN) << 16) + File_h.bfOffBits; File_h.bfOffBits = (getc(IN) << 24) + File_h.bfOffBits; /* INFO HEADER */ /* ------------- */ Info_h.biSize = getc(IN); Info_h.biSize = (getc(IN) << 8) + Info_h.biSize; Info_h.biSize = (getc(IN) << 16) + Info_h.biSize; Info_h.biSize = (getc(IN) << 24) + Info_h.biSize; Info_h.biWidth = getc(IN); Info_h.biWidth = (getc(IN) << 8) + Info_h.biWidth; Info_h.biWidth = (getc(IN) << 16) + Info_h.biWidth; Info_h.biWidth = (getc(IN) << 24) + Info_h.biWidth; w = Info_h.biWidth; Info_h.biHeight = getc(IN); Info_h.biHeight = (getc(IN) << 8) + Info_h.biHeight; Info_h.biHeight = (getc(IN) << 16) + Info_h.biHeight; Info_h.biHeight = (getc(IN) << 24) + Info_h.biHeight; h = Info_h.biHeight; Info_h.biPlanes = getc(IN); Info_h.biPlanes = (getc(IN) << 8) + Info_h.biPlanes; Info_h.biBitCount = getc(IN); Info_h.biBitCount = (getc(IN) << 8) + Info_h.biBitCount; Info_h.biCompression = getc(IN); Info_h.biCompression = (getc(IN) << 8) + Info_h.biCompression; Info_h.biCompression = (getc(IN) << 16) + Info_h.biCompression; Info_h.biCompression = (getc(IN) << 24) + Info_h.biCompression; Info_h.biSizeImage = getc(IN); Info_h.biSizeImage = (getc(IN) << 8) + Info_h.biSizeImage; Info_h.biSizeImage = (getc(IN) << 16) + Info_h.biSizeImage; Info_h.biSizeImage = (getc(IN) << 24) + Info_h.biSizeImage; Info_h.biXpelsPerMeter = getc(IN); Info_h.biXpelsPerMeter = (getc(IN) << 8) + Info_h.biXpelsPerMeter; Info_h.biXpelsPerMeter = (getc(IN) << 16) + Info_h.biXpelsPerMeter; Info_h.biXpelsPerMeter = (getc(IN) << 24) + Info_h.biXpelsPerMeter; Info_h.biYpelsPerMeter = getc(IN); Info_h.biYpelsPerMeter = (getc(IN) << 8) + Info_h.biYpelsPerMeter; Info_h.biYpelsPerMeter = (getc(IN) << 16) + Info_h.biYpelsPerMeter; Info_h.biYpelsPerMeter = (getc(IN) << 24) + Info_h.biYpelsPerMeter; Info_h.biClrUsed = getc(IN); Info_h.biClrUsed = (getc(IN) << 8) + Info_h.biClrUsed; Info_h.biClrUsed = (getc(IN) << 16) + Info_h.biClrUsed; Info_h.biClrUsed = (getc(IN) << 24) + Info_h.biClrUsed; Info_h.biClrImportant = getc(IN); Info_h.biClrImportant = (getc(IN) << 8) + Info_h.biClrImportant; Info_h.biClrImportant = (getc(IN) << 16) + Info_h.biClrImportant; Info_h.biClrImportant = (getc(IN) << 24) + Info_h.biClrImportant; /* Read the data and store them in the OUT file */ if (Info_h.biBitCount == 24) { numcomps = 3; color_space = CLRSPC_SRGB; /* initialize image components */ memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); for(i = 0; i < numcomps; i++) { cmptparm[i].prec = 8; cmptparm[i].bpp = 8; cmptparm[i].sgnd = 0; cmptparm[i].dx = subsampling_dx; cmptparm[i].dy = subsampling_dy; cmptparm[i].w = w; cmptparm[i].h = h; } /* create the image */ image = opj_image_create(numcomps, &cmptparm[0], color_space); if(!image) { fclose(IN); return NULL; } /* set image offset and reference grid */ image->x0 = parameters->image_offset_x0; image->y0 = parameters->image_offset_y0; image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1; image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1; /* set image data */ /* Place the cursor at the beginning of the image information */ fseek(IN, 0, SEEK_SET); fseek(IN, File_h.bfOffBits, SEEK_SET); W = Info_h.biWidth; H = Info_h.biHeight; /* PAD = 4 - (3 * W) % 4; */ /* PAD = (PAD == 4) ? 0 : PAD; */ PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0; RGB = (unsigned char *) malloc((3 * W + PAD) * H * sizeof(unsigned char)); fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN); index = 0; for(y = 0; y < (int)H; y++) { unsigned char *scanline = RGB + (3 * W + PAD) * (H - 1 - y); for(x = 0; x < (int)W; x++) { unsigned char *pixel = &scanline[3 * x]; image->comps[0].data[index] = pixel[2]; /* R */ image->comps[1].data[index] = pixel[1]; /* G */ image->comps[2].data[index] = pixel[0]; /* B */ index++; } } free(RGB); } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 0) { table_R = (unsigned char *) malloc(256 * sizeof(unsigned char)); table_G = (unsigned char *) malloc(256 * sizeof(unsigned char)); table_B = (unsigned char *) malloc(256 * sizeof(unsigned char)); for (j = 0; j < Info_h.biClrUsed; j++) { table_B[j] = getc(IN); table_G[j] = getc(IN); table_R[j] = getc(IN); getc(IN); if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j]) gray_scale = 0; } /* Place the cursor at the beginning of the image information */ fseek(IN, 0, SEEK_SET); fseek(IN, File_h.bfOffBits, SEEK_SET); W = Info_h.biWidth; H = Info_h.biHeight; if (Info_h.biWidth % 2) W++; numcomps = gray_scale ? 1 : 3; color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB; /* initialize image components */ memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); for(i = 0; i < numcomps; i++) { cmptparm[i].prec = 8; cmptparm[i].bpp = 8; cmptparm[i].sgnd = 0; cmptparm[i].dx = subsampling_dx; cmptparm[i].dy = subsampling_dy; cmptparm[i].w = w; cmptparm[i].h = h; } /* create the image */ image = opj_image_create(numcomps, &cmptparm[0], color_space); if(!image) { fclose(IN); return NULL; } /* set image offset and reference grid */ image->x0 = parameters->image_offset_x0; image->y0 = parameters->image_offset_y0; image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1; image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1; /* set image data */ RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char)); fread(RGB, sizeof(unsigned char), W * H, IN); if (gray_scale) { index = 0; for (j = 0; j < W * H; j++) { if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) { image->comps[0].data[index] = table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]]; index++; } } } else { index = 0; for (j = 0; j < W * H; j++) { if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) { unsigned char pixel_index = RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]; image->comps[0].data[index] = table_R[pixel_index]; image->comps[1].data[index] = table_G[pixel_index]; image->comps[2].data[index] = table_B[pixel_index]; index++; } } } free(RGB); } else if (Info_h.biBitCount == 8 && Info_h.biCompression == 1) { table_R = (unsigned char *) malloc(256 * sizeof(unsigned char)); table_G = (unsigned char *) malloc(256 * sizeof(unsigned char)); table_B = (unsigned char *) malloc(256 * sizeof(unsigned char)); for (j = 0; j < Info_h.biClrUsed; j++) { table_B[j] = getc(IN); table_G[j] = getc(IN); table_R[j] = getc(IN); getc(IN); if (table_R[j] != table_G[j] && table_R[j] != table_B[j] && table_G[j] != table_B[j]) gray_scale = 0; } numcomps = gray_scale ? 1 : 3; color_space = gray_scale ? CLRSPC_GRAY : CLRSPC_SRGB; /* initialize image components */ memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); for(i = 0; i < numcomps; i++) { cmptparm[i].prec = 8; cmptparm[i].bpp = 8; cmptparm[i].sgnd = 0; cmptparm[i].dx = subsampling_dx; cmptparm[i].dy = subsampling_dy; cmptparm[i].w = w; cmptparm[i].h = h; } /* create the image */ image = opj_image_create(numcomps, &cmptparm[0], color_space); if(!image) { fclose(IN); return NULL; } /* set image offset and reference grid */ image->x0 = parameters->image_offset_x0; image->y0 = parameters->image_offset_y0; image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1; image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1; /* set image data */ /* Place the cursor at the beginning of the image information */ fseek(IN, 0, SEEK_SET); fseek(IN, File_h.bfOffBits, SEEK_SET); RGB = (unsigned char *) malloc(Info_h.biWidth * Info_h.biHeight * sizeof(unsigned char)); while (not_end_file) { v = getc(IN); if (v) { v2 = getc(IN); for (i = 0; i < (int) v; i++) { RGB[line * Info_h.biWidth + col] = v2; col++; } } else { v = getc(IN); switch (v) { case 0: col = 0; line++; break; case 1: line++; not_end_file = 0; break; case 2: fprintf(stderr,"No Delta supported\n"); opj_image_destroy(image); fclose(IN); return NULL; default: for (i = 0; i < v; i++) { v2 = getc(IN); RGB[line * Info_h.biWidth + col] = v2; col++; } if (v % 2) v2 = getc(IN); break; } } } if (gray_scale) { index = 0; for (line = 0; line < Info_h.biHeight; line++) { for (col = 0; col < Info_h.biWidth; col++) { image->comps[0].data[index] = table_R[(int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col]]; index++; } } } else { index = 0; for (line = 0; line < Info_h.biHeight; line++) { for (col = 0; col < Info_h.biWidth; col++) { unsigned char pixel_index = (int)RGB[(Info_h.biHeight - line - 1) * Info_h.biWidth + col]; image->comps[0].data[index] = table_R[pixel_index]; image->comps[1].data[index] = table_G[pixel_index]; image->comps[2].data[index] = table_B[pixel_index]; index++; } } } free(RGB); } else { fprintf(stderr, "Other system than 24 bits/pixels or 8 bits (no RLE coding) is not yet implemented [%d]\n", Info_h.biBitCount); } fclose(IN); } return image; }
/** Convert a FIBITMAP to a OpenJPEG image @param format_id Plugin ID @param dib FreeImage image @param parameters Compression parameters @return Returns the converted image if successful, returns NULL otherwise */ opj_image_t* FIBITMAPToJ2KImage(int format_id, FIBITMAP *dib, const opj_cparameters_t *parameters) { int prec, numcomps, x, y, index; OPJ_COLOR_SPACE color_space; opj_image_cmptparm_t cmptparm[4]; // maximum of 4 components opj_image_t *image = NULL; // image to encode try { int w = FreeImage_GetWidth(dib); int h = FreeImage_GetHeight(dib); // get image characteristics FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib); if(image_type == FIT_BITMAP) { // standard image ... prec = 8; switch(FreeImage_GetColorType(dib)) { case FIC_MINISBLACK: numcomps = 1; color_space = OPJ_CLRSPC_GRAY; break; case FIC_RGB: if(FreeImage_GetBPP(dib) == 32) { // 32-bit image with a fully opaque layer numcomps = 4; color_space = OPJ_CLRSPC_SRGB; } else { // 24-bit image numcomps = 3; color_space = OPJ_CLRSPC_SRGB; } break; case FIC_RGBALPHA: numcomps = 4; color_space = OPJ_CLRSPC_SRGB; break; default: return NULL; } } else { // HDR image ... prec = 16; switch(image_type) { case FIT_UINT16: numcomps = 1; color_space = OPJ_CLRSPC_GRAY; break; case FIT_RGB16: numcomps = 3; color_space = OPJ_CLRSPC_SRGB; break; case FIT_RGBA16: numcomps = 4; color_space = OPJ_CLRSPC_SRGB; break; default: return NULL; } } // initialize image components memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t)); for(int i = 0; i < numcomps; i++) { cmptparm[i].dx = parameters->subsampling_dx; cmptparm[i].dy = parameters->subsampling_dy; cmptparm[i].w = w; cmptparm[i].h = h; cmptparm[i].prec = prec; cmptparm[i].bpp = prec; cmptparm[i].sgnd = 0; } // create the image image = opj_image_create(numcomps, &cmptparm[0], color_space); if(!image) { throw FI_MSG_ERROR_DIB_MEMORY; } // set image offset and reference grid image->x0 = parameters->image_offset_x0; image->y0 = parameters->image_offset_y0; image->x1 = parameters->image_offset_x0 + (w - 1) * parameters->subsampling_dx + 1; image->y1 = parameters->image_offset_y0 + (h - 1) * parameters->subsampling_dy + 1; // set image data if(prec == 8) { switch(numcomps) { case 1: index = 0; for(y = 0; y < h; y++) { BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y); for(x = 0; x < w; x++) { image->comps[0].data[index] = bits[x]; index++; } } break; case 3: index = 0; for(y = 0; y < h; y++) { BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y); for(x = 0; x < w; x++) { image->comps[0].data[index] = bits[FI_RGBA_RED]; image->comps[1].data[index] = bits[FI_RGBA_GREEN]; image->comps[2].data[index] = bits[FI_RGBA_BLUE]; bits += 3; index++; } } break; case 4: index = 0; for(y = 0; y < h; y++) { BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y); for(x = 0; x < w; x++) { image->comps[0].data[index] = bits[FI_RGBA_RED]; image->comps[1].data[index] = bits[FI_RGBA_GREEN]; image->comps[2].data[index] = bits[FI_RGBA_BLUE]; image->comps[3].data[index] = bits[FI_RGBA_ALPHA]; bits += 4; index++; } } break; } } else if(prec == 16) { switch(numcomps) { case 1: index = 0; for(y = 0; y < h; y++) { WORD *bits = (WORD*)FreeImage_GetScanLine(dib, h - 1 - y); for(x = 0; x < w; x++) { image->comps[0].data[index] = bits[x]; index++; } } break; case 3: index = 0; for(y = 0; y < h; y++) { FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, h - 1 - y); for(x = 0; x < w; x++) { image->comps[0].data[index] = bits[x].red; image->comps[1].data[index] = bits[x].green; image->comps[2].data[index] = bits[x].blue; index++; } } break; case 4: index = 0; for(y = 0; y < h; y++) { FIRGBA16 *bits = (FIRGBA16*)FreeImage_GetScanLine(dib, h - 1 - y); for(x = 0; x < w; x++) { image->comps[0].data[index] = bits[x].red; image->comps[1].data[index] = bits[x].green; image->comps[2].data[index] = bits[x].blue; image->comps[3].data[index] = bits[x].alpha; index++; } } break; } } return image; } catch (const char *text) { if(image) opj_image_destroy(image); FreeImage_OutputMessageProc(format_id, text); return NULL; } }
static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *parameters) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); opj_image_cmptparm_t cmptparm[4] = {{0}}; opj_image_t *img; int i; int sub_dx[4]; int sub_dy[4]; int numcomps; OPJ_COLOR_SPACE color_space = CLRSPC_UNKNOWN; sub_dx[0] = sub_dx[3] = 1; sub_dy[0] = sub_dy[3] = 1; sub_dx[1] = sub_dx[2] = 1 << desc->log2_chroma_w; sub_dy[1] = sub_dy[2] = 1 << desc->log2_chroma_h; numcomps = desc->nb_components; switch (avctx->pix_fmt) { case AV_PIX_FMT_GRAY8: case AV_PIX_FMT_YA8: case AV_PIX_FMT_GRAY16: case AV_PIX_FMT_YA16: color_space = CLRSPC_GRAY; break; case AV_PIX_FMT_RGB24: case AV_PIX_FMT_RGBA: case AV_PIX_FMT_RGB48: case AV_PIX_FMT_RGBA64: case AV_PIX_FMT_GBR24P: case AV_PIX_FMT_GBRP9: case AV_PIX_FMT_GBRP10: case AV_PIX_FMT_GBRP12: case AV_PIX_FMT_GBRP14: case AV_PIX_FMT_GBRP16: case AV_PIX_FMT_XYZ12: color_space = CLRSPC_SRGB; break; case AV_PIX_FMT_YUV410P: case AV_PIX_FMT_YUV411P: case AV_PIX_FMT_YUV420P: case AV_PIX_FMT_YUV422P: case AV_PIX_FMT_YUV440P: case AV_PIX_FMT_YUV444P: case AV_PIX_FMT_YUVA420P: case AV_PIX_FMT_YUVA422P: case AV_PIX_FMT_YUVA444P: case AV_PIX_FMT_YUV420P9: case AV_PIX_FMT_YUV422P9: case AV_PIX_FMT_YUV444P9: case AV_PIX_FMT_YUVA420P9: case AV_PIX_FMT_YUVA422P9: case AV_PIX_FMT_YUVA444P9: case AV_PIX_FMT_YUV420P10: case AV_PIX_FMT_YUV422P10: case AV_PIX_FMT_YUV444P10: case AV_PIX_FMT_YUVA420P10: case AV_PIX_FMT_YUVA422P10: case AV_PIX_FMT_YUVA444P10: case AV_PIX_FMT_YUV420P12: case AV_PIX_FMT_YUV422P12: case AV_PIX_FMT_YUV444P12: case AV_PIX_FMT_YUV420P14: case AV_PIX_FMT_YUV422P14: case AV_PIX_FMT_YUV444P14: case AV_PIX_FMT_YUV420P16: case AV_PIX_FMT_YUV422P16: case AV_PIX_FMT_YUV444P16: case AV_PIX_FMT_YUVA420P16: case AV_PIX_FMT_YUVA422P16: case AV_PIX_FMT_YUVA444P16: color_space = CLRSPC_SYCC; break; default: av_log(avctx, AV_LOG_ERROR, "The requested pixel format '%s' is not supported\n", av_get_pix_fmt_name(avctx->pix_fmt)); return NULL; } for (i = 0; i < numcomps; i++) { cmptparm[i].prec = desc->comp[i].depth_minus1 + 1; cmptparm[i].bpp = desc->comp[i].depth_minus1 + 1; cmptparm[i].sgnd = 0; cmptparm[i].dx = sub_dx[i]; cmptparm[i].dy = sub_dy[i]; cmptparm[i].w = (avctx->width + sub_dx[i] - 1) / sub_dx[i]; cmptparm[i].h = (avctx->height + sub_dy[i] - 1) / sub_dy[i]; } img = opj_image_create(numcomps, cmptparm, color_space); // x0, y0 is the top left corner of the image // x1, y1 is the width, height of the reference grid img->x0 = 0; img->y0 = 0; img->x1 = (avctx->width - 1) * parameters->subsampling_dx + 1; img->y1 = (avctx->height - 1) * parameters->subsampling_dy + 1; return img; }
static opj_image_t* convert_gray_to_rgb(opj_image_t* original) { OPJ_UINT32 compno; opj_image_t* l_new_image = NULL; opj_image_cmptparm_t* l_new_components = NULL; l_new_components = (opj_image_cmptparm_t*)malloc((original->numcomps + 2U) * sizeof(opj_image_cmptparm_t)); if (l_new_components == NULL) { fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for RGB image!\n"); opj_image_destroy(original); return NULL; } l_new_components[0].bpp = l_new_components[1].bpp = l_new_components[2].bpp = original->comps[0].bpp; l_new_components[0].dx = l_new_components[1].dx = l_new_components[2].dx = original->comps[0].dx; l_new_components[0].dy = l_new_components[1].dy = l_new_components[2].dy = original->comps[0].dy; l_new_components[0].h = l_new_components[1].h = l_new_components[2].h = original->comps[0].h; l_new_components[0].w = l_new_components[1].w = l_new_components[2].w = original->comps[0].w; l_new_components[0].prec = l_new_components[1].prec = l_new_components[2].prec = original->comps[0].prec; l_new_components[0].sgnd = l_new_components[1].sgnd = l_new_components[2].sgnd = original->comps[0].sgnd; l_new_components[0].x0 = l_new_components[1].x0 = l_new_components[2].x0 = original->comps[0].x0; l_new_components[0].y0 = l_new_components[1].y0 = l_new_components[2].y0 = original->comps[0].y0; for(compno = 1U; compno < original->numcomps; ++compno) { l_new_components[compno+2U].bpp = original->comps[compno].bpp; l_new_components[compno+2U].dx = original->comps[compno].dx; l_new_components[compno+2U].dy = original->comps[compno].dy; l_new_components[compno+2U].h = original->comps[compno].h; l_new_components[compno+2U].w = original->comps[compno].w; l_new_components[compno+2U].prec = original->comps[compno].prec; l_new_components[compno+2U].sgnd = original->comps[compno].sgnd; l_new_components[compno+2U].x0 = original->comps[compno].x0; l_new_components[compno+2U].y0 = original->comps[compno].y0; } l_new_image = opj_image_create(original->numcomps + 2U, l_new_components, OPJ_CLRSPC_SRGB); free(l_new_components); if (l_new_image == NULL) { fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for RGB image!\n"); opj_image_destroy(original); return NULL; } l_new_image->x0 = original->x0; l_new_image->x1 = original->x1; l_new_image->y0 = original->y0; l_new_image->y1 = original->y1; l_new_image->comps[0].factor = l_new_image->comps[1].factor = l_new_image->comps[2].factor = original->comps[0].factor; l_new_image->comps[0].alpha = l_new_image->comps[1].alpha = l_new_image->comps[2].alpha = original->comps[0].alpha; l_new_image->comps[0].resno_decoded = l_new_image->comps[1].resno_decoded = l_new_image->comps[2].resno_decoded = original->comps[0].resno_decoded; memcpy(l_new_image->comps[0].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32)); memcpy(l_new_image->comps[1].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32)); memcpy(l_new_image->comps[2].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32)); for(compno = 1U; compno < original->numcomps; ++compno) { l_new_image->comps[compno+2U].factor = original->comps[compno].factor; l_new_image->comps[compno+2U].alpha = original->comps[compno].alpha; l_new_image->comps[compno+2U].resno_decoded = original->comps[compno].resno_decoded; memcpy(l_new_image->comps[compno+2U].data, original->comps[compno].data, original->comps[compno].w * original->comps[compno].h * sizeof(OPJ_INT32)); } opj_image_destroy(original); return l_new_image; }
static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *parameters) { opj_image_cmptparm_t *cmptparm; opj_image_t *img; int i; int bpp = 8; int sub_dx[4]; int sub_dy[4]; int numcomps = 0; OPJ_COLOR_SPACE color_space = CLRSPC_UNKNOWN; sub_dx[0] = sub_dx[3] = 1; sub_dy[0] = sub_dy[3] = 1; sub_dx[1] = sub_dx[2] = 1<<av_pix_fmt_descriptors[avctx->pix_fmt].log2_chroma_w; sub_dy[1] = sub_dy[2] = 1<<av_pix_fmt_descriptors[avctx->pix_fmt].log2_chroma_h; switch (avctx->pix_fmt) { case PIX_FMT_GRAY8: color_space = CLRSPC_GRAY; numcomps = 1; break; case PIX_FMT_RGB24: color_space = CLRSPC_SRGB; numcomps = 3; break; case PIX_FMT_RGBA: color_space = CLRSPC_SRGB; numcomps = 4; break; case PIX_FMT_RGB48: color_space = CLRSPC_SRGB; numcomps = 3; bpp = 16; break; case PIX_FMT_YUV420P: color_space = CLRSPC_SYCC; numcomps = 3; break; case PIX_FMT_YUV422P: color_space = CLRSPC_SYCC; numcomps = 3; break; case PIX_FMT_YUV440P: color_space = CLRSPC_SYCC; numcomps = 3; break; case PIX_FMT_YUV444P: color_space = CLRSPC_SYCC; numcomps = 3; break; case PIX_FMT_YUVA420P: color_space = CLRSPC_SYCC; numcomps = 4; break; case PIX_FMT_YUV420P9: case PIX_FMT_YUV422P9: case PIX_FMT_YUV444P9: color_space = CLRSPC_SYCC; numcomps = 3; bpp = 9; break; case PIX_FMT_YUV420P10: case PIX_FMT_YUV422P10: case PIX_FMT_YUV444P10: color_space = CLRSPC_SYCC; numcomps = 3; bpp = 10; break; case PIX_FMT_YUV420P16: case PIX_FMT_YUV422P16: case PIX_FMT_YUV444P16: color_space = CLRSPC_SYCC; numcomps = 3; bpp = 16; break; default: av_log(avctx, AV_LOG_ERROR, "The requested pixel format '%s' is not supported\n", av_get_pix_fmt_name(avctx->pix_fmt)); return NULL; } cmptparm = av_mallocz(numcomps * sizeof(opj_image_cmptparm_t)); if (!cmptparm) { av_log(avctx, AV_LOG_ERROR, "Not enough memory"); return NULL; } for (i = 0; i < numcomps; i++) { cmptparm[i].prec = bpp; cmptparm[i].bpp = bpp; cmptparm[i].sgnd = 0; cmptparm[i].dx = sub_dx[i]; cmptparm[i].dy = sub_dy[i]; cmptparm[i].w = avctx->width / sub_dx[i]; cmptparm[i].h = avctx->height / sub_dy[i]; } img = opj_image_create(numcomps, cmptparm, color_space); av_freep(&cmptparm); return img; }
/*! * pixConvertToOpjImage() * * Input: pix (8 or 32 bpp) * Return: opj_image, or NULL on error * * Notes: * (1) Input pix is 8 bpp grayscale, 32 bpp rgb, or 32 bpp rgba. * (2) Gray + alpha pix are all represented as rgba. */ static opj_image_t * pixConvertToOpjImage(PIX *pix) { l_int32 i, j, k, w, h, d, spp, wpl; OPJ_COLOR_SPACE colorspace; l_int32 *ir = NULL; l_int32 *ig = NULL; l_int32 *ib = NULL; l_int32 *ia = NULL; l_uint32 *line, *data; opj_image_t *image; opj_image_cmptparm_t cmptparm[4]; PROCNAME("pixConvertToOpjImage"); if (!pix) return (opj_image_t *)ERROR_PTR("pix not defined", procName, NULL); pixGetDimensions(pix, &w, &h, &d); if (d != 8 && d != 32) { L_ERROR("invalid depth: %d\n", procName, d); return NULL; } /* Allocate the opj_image. */ spp = pixGetSpp(pix); memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t)); for (i = 0; i < spp; i++) { cmptparm[i].prec = 8; cmptparm[i].bpp = 8; cmptparm[i].sgnd = 0; cmptparm[i].dx = 1; cmptparm[i].dy = 1; cmptparm[i].w = w; cmptparm[i].h = h; } colorspace = (spp == 1) ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB; if ((image = opj_image_create(spp, &cmptparm[0], colorspace)) == NULL) return (opj_image_t *)ERROR_PTR("image not made", procName, NULL); image->x0 = 0; image->y0 = 0; image->x1 = w; image->y1 = h; /* Set the component pointers */ ir = image->comps[0].data; if (spp > 1) { ig = image->comps[1].data; ib = image->comps[2].data; } if(spp == 4) ia = image->comps[3].data; /* Transfer the data from the pix */ data = pixGetData(pix); wpl = pixGetWpl(pix); for (i = 0, k = 0; i < h; i++) { line = data + i * wpl; for (j = 0; j < w; j++, k++) { if (spp == 1) { ir[k] = GET_DATA_BYTE(line, j); } else if (spp > 1) { ir[k] = GET_DATA_BYTE(line + j, COLOR_RED); ig[k] = GET_DATA_BYTE(line + j, COLOR_GREEN); ib[k] = GET_DATA_BYTE(line + j, COLOR_BLUE); } if (spp == 4) ia[k] = GET_DATA_BYTE(line + j, L_ALPHA_CHANNEL); } } return image; }