bool opj_set_MCT(opj_cparameters_t *parameters,OPJ_FLOAT32 * pEncodingMatrix,OPJ_INT32 * p_dc_shift,OPJ_UINT32 pNbComp) { OPJ_UINT32 l_matrix_size = pNbComp * pNbComp * sizeof(OPJ_FLOAT32); OPJ_UINT32 l_dc_shift_size = pNbComp * sizeof(OPJ_INT32); OPJ_UINT32 l_mct_total_size = l_matrix_size + l_dc_shift_size; // add MCT capability int rsiz = (int)parameters->cp_rsiz | (int)MCT; parameters->cp_rsiz = (OPJ_RSIZ_CAPABILITIES)rsiz; parameters->irreversible = 1; // use array based MCT parameters->tcp_mct = 2; parameters->mct_data = opj_malloc(l_mct_total_size); if (! parameters->mct_data) { return false; } memcpy(parameters->mct_data,pEncodingMatrix,l_matrix_size); memcpy(((OPJ_BYTE *) parameters->mct_data) + l_matrix_size,p_dc_shift,l_dc_shift_size); return true; }
opj_thread_t* opj_thread_create( opj_thread_fn thread_fn, void* user_data ) { opj_thread_t* thread; assert( thread_fn ); thread = (opj_thread_t*) opj_malloc( sizeof(opj_thread_t) ); if( !thread ) return NULL; thread->thread_fn = thread_fn; thread->user_data = user_data; thread->hThread = (HANDLE)_beginthreadex(NULL, 0, opj_thread_callback_adapter, thread, 0, NULL); if( thread->hThread == NULL ) { opj_free( thread ); return NULL; } return thread; }
opj_image_t* OPJ_CALLCONV opj_image_create(int numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) { int compno; opj_image_t *image = NULL; image = (opj_image_t*) opj_calloc(1, sizeof(opj_image_t)); if(image) { image->color_space = clrspc; image->numcomps = numcmpts; /* allocate memory for the per-component information */ image->comps = (opj_image_comp_t*)opj_malloc(image->numcomps * sizeof(opj_image_comp_t)); if(!image->comps) { fprintf(stderr,"Unable to allocate memory for image.\n"); opj_image_destroy(image); return NULL; } /* create the individual image components */ for(compno = 0; compno < numcmpts; compno++) { opj_image_comp_t *comp = &image->comps[compno]; comp->dx = cmptparms[compno].dx; comp->dy = cmptparms[compno].dy; comp->w = cmptparms[compno].w; comp->h = cmptparms[compno].h; comp->x0 = cmptparms[compno].x0; comp->y0 = cmptparms[compno].y0; comp->prec = cmptparms[compno].prec; comp->bpp = cmptparms[compno].bpp; comp->sgnd = cmptparms[compno].sgnd; comp->data = (int*) opj_calloc(comp->w * comp->h, sizeof(int)); if(!comp->data) { fprintf(stderr,"Unable to allocate memory for image.\n"); opj_image_destroy(image); return NULL; } } } return image; }
void opj_cond_wait(opj_cond_t* cond, opj_mutex_t* mutex) { opj_cond_waiter_list_t* item; HANDLE hEvent = (HANDLE) TlsGetValue( TLSKey ); if (hEvent == NULL) { hEvent = CreateEvent(NULL, /* security attributes */ 0, /* manual reset = no */ 0, /* initial state = unsignaled */ NULL /* no name */); assert(hEvent); TlsSetValue( TLSKey, hEvent ); } /* Insert the waiter into the waiter list of the condition */ opj_mutex_lock(cond->internal_mutex); item = (opj_cond_waiter_list_t*)opj_malloc(sizeof(opj_cond_waiter_list_t)); assert(item != NULL); item->hEvent = hEvent; item->next = cond->waiter_list; cond->waiter_list = item; opj_mutex_unlock(cond->internal_mutex); /* Release the client mutex before waiting for the event being signaled */ opj_mutex_unlock(mutex); /* Ideally we would check that we do not get WAIT_FAILED but it is hard */ /* to report a failure. */ WaitForSingleObject(hEvent, INFINITE); /* Reacquire the client mutex */ opj_mutex_lock(mutex); }
opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format) { opj_dinfo_t *dinfo = (opj_dinfo_t*)opj_malloc(sizeof(opj_dinfo_t)); if(!dinfo) return NULL; dinfo->is_decompressor = true; switch(format) { case CODEC_J3D: case CODEC_J2K: /* get a J3D decoder handle */ dinfo->j3d_handle = (void*)j3d_create_decompress((opj_common_ptr)dinfo); if(!dinfo->j3d_handle) { opj_free(dinfo); return NULL; } break; default: opj_free(dinfo); return NULL; } dinfo->codec_format = format; return dinfo; }
opj_thread_t* opj_thread_create( opj_thread_fn thread_fn, void* user_data ) { pthread_attr_t attr; opj_thread_t* thread; assert( thread_fn ); thread = (opj_thread_t*) opj_malloc( sizeof(opj_thread_t) ); if( !thread ) return NULL; thread->thread_fn = thread_fn; thread->user_data = user_data; pthread_attr_init( &attr ); pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); if( pthread_create( &(thread->thread), &attr, opj_thread_callback_adapter, (void *) thread ) != 0 ) { opj_free( thread ); return NULL; } return thread; }
OPJ_BOOL OPJ_CALLCONV fread_jpip( const char fname[], jpip_dec_param_t *dec) { int infd; if(( infd = open( fname, O_RDONLY)) == -1){ fprintf( stderr, "file %s not exist\n", fname); return OPJ_FALSE; } if(!(dec->jpiplen = (Byte8_t)get_filesize(infd))) return OPJ_FALSE; dec->jpipstream = (Byte_t *)opj_malloc( dec->jpiplen); if( read( infd, dec->jpipstream, dec->jpiplen) != (int)dec->jpiplen){ fprintf( stderr, "file reading error\n"); opj_free( dec->jpipstream); return OPJ_FALSE; } close(infd); return OPJ_TRUE; }
ihdrbox_param_t * get_SIZ_from_jpipstream( Byte_t *jpipstream, msgqueue_param_t *msgqueue, Byte8_t csn) { ihdrbox_param_t *ihdrbox; Byte_t *j2kstream; Byte8_t j2klen; SIZmarker_param_t SIZ; j2kstream = recons_j2kmainhead( msgqueue, jpipstream, csn, &j2klen); if( !get_mainheader_from_j2kstream( j2kstream, &SIZ, NULL)){ opj_free( j2kstream); return NULL; } ihdrbox = (ihdrbox_param_t *)opj_malloc( sizeof(ihdrbox_param_t)); ihdrbox->width = SIZ.Xsiz; ihdrbox->height = SIZ.Ysiz; ihdrbox->nc = SIZ.Csiz; ihdrbox->bpc = SIZ.Ssiz[0]; opj_free( j2kstream); return ihdrbox; }
static opj_worker_thread_job_t* opj_thread_pool_get_next_job(opj_thread_pool_t* tp, opj_worker_thread_t* worker_thread, OPJ_BOOL signal_job_finished) { while( OPJ_TRUE ) { opj_job_list_t* top_job_iter; opj_mutex_lock(tp->mutex); if( signal_job_finished ) { signal_job_finished = OPJ_FALSE; tp->pending_jobs_count --; /*printf("tp=%p, remaining jobs: %d\n", tp, tp->pending_jobs_count);*/ if( tp->pending_jobs_count <= tp->signaling_threshold ) opj_cond_signal(tp->cond); } if( tp->state == OPJWTS_STOP ) { opj_mutex_unlock(tp->mutex); return NULL; } top_job_iter = tp->job_queue; if( top_job_iter ) { opj_worker_thread_job_t* job; tp->job_queue = top_job_iter->next; job = top_job_iter->job; opj_mutex_unlock(tp->mutex); opj_free(top_job_iter); return job; } /* opj_waiting(); */ if( !worker_thread->marked_as_waiting ) { opj_worker_thread_list_t* item; worker_thread->marked_as_waiting = OPJ_TRUE; tp->waiting_worker_thread_count ++; assert(tp->waiting_worker_thread_count <= tp->worker_threads_count); item= (opj_worker_thread_list_t*) opj_malloc(sizeof(opj_worker_thread_list_t)); if( item == NULL ) { tp->state = OPJWTS_ERROR; opj_cond_signal(tp->cond); opj_mutex_unlock(tp->mutex); return NULL; } item->worker_thread = worker_thread; item->next = tp->waiting_worker_thread_list; tp->waiting_worker_thread_list = item; } /* printf("signaling that worker thread is ready\n"); */ opj_cond_signal(tp->cond); opj_mutex_lock(worker_thread->mutex); opj_mutex_unlock(tp->mutex); /* printf("waiting for job\n"); */ opj_cond_wait( worker_thread->cond, worker_thread->mutex ); opj_mutex_unlock(worker_thread->mutex); /* printf("got job\n"); */ } }
/* -------------------------------------------------------------------------- -------------------- MAIN METHOD, CALLED BY JAVA -----------------------*/ JNIEXPORT jint JNICALL Java_org_openJpeg_OpenJPEGJavaDecoder_internalDecodeJ2KtoImage(JNIEnv *env, jobject obj, jobjectArray javaParameters) { int argc; /* To simulate the command line parameters (taken from the javaParameters variable) and be able to re-use the */ char **argv; /* 'parse_cmdline_decoder' method taken from the j2k_to_image project */ opj_dparameters_t parameters; /* decompression parameters */ img_fol_t img_fol; opj_event_mgr_t event_mgr; /* event manager */ opj_image_t *image = NULL; FILE *fsrc = NULL; unsigned char *src = NULL; int file_length; int num_images; int i,j,imageno; opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ opj_cio_t *cio = NULL; int w,h; long min_value, max_value; short tempS; unsigned char tempUC, tempUC1, tempUC2; /* ==> Access variables to the Java member variables*/ jsize arraySize; jclass cls; jobject object; jboolean isCopy; jfieldID fid; jbyteArray jba; jshortArray jsa; jintArray jia; jbyte *jbBody, *ptrBBody; jshort *jsBody, *ptrSBody; jint *jiBody, *ptrIBody; callback_variables_t msgErrorCallback_vars; /* <=== access variable to Java member variables */ int *ptr, *ptr1, *ptr2; /* <== To transfer the decoded image to Java*/ /* configure the event 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; /* JNI reference to the calling class*/ cls = (*env)->GetObjectClass(env, obj); /* Pointers to be able to call a Java method for all the info and error messages*/ msgErrorCallback_vars.env = env; msgErrorCallback_vars.jobj = &obj; msgErrorCallback_vars.message_mid = (*env)->GetMethodID(env, cls, "logMessage", "(Ljava/lang/String;)V"); msgErrorCallback_vars.error_mid = (*env)->GetMethodID(env, cls, "logError", "(Ljava/lang/String;)V"); /* Get the String[] containing the parameters, and converts it into a char** to simulate command line arguments.*/ arraySize = (*env)->GetArrayLength(env, javaParameters); argc = (int) arraySize +1; argv = opj_malloc(argc*sizeof(char*)); argv[0] = "ProgramName.exe"; /* The program name: useless*/ j=0; for (i=1; i<argc; i++) { object = (*env)->GetObjectArrayElement(env, javaParameters, i-1); argv[i] = (char*)(*env)->GetStringUTFChars(env, object, &isCopy); } /*printf("C: decoder params = "); for (i=0; i<argc; i++) { printf("[%s]",argv[i]); } printf("\n");*/ /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); parameters.decod_format = J2K_CFMT; /* parse input and get user encoding parameters */ if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol) == 1) { /* Release the Java arguments array*/ for (i=1; i<argc; i++) (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]); return -1; } /* Release the Java arguments array*/ for (i=1; i<argc; i++) (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]); num_images=1; /* Get additional information from the Java object variables*/ fid = (*env)->GetFieldID(env, cls,"skippedResolutions", "I"); parameters.cp_reduce = (short) (*env)->GetIntField(env, obj, fid); /*Decoding image one by one*/ for(imageno = 0; imageno < num_images ; imageno++) { image = NULL; fprintf(stderr,"\n"); /* read the input file and put it in memory into the 'src' object, if the -i option is given in JavaParameters. Implemented for debug purpose. */ /* -------------------------------------------------------------- */ if (parameters.infile && parameters.infile[0]!='\0') { /*printf("C: opening [%s]\n", parameters.infile);*/ fsrc = fopen(parameters.infile, "rb"); if (!fsrc) { fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile); return 1; } fseek(fsrc, 0, SEEK_END); file_length = ftell(fsrc); fseek(fsrc, 0, SEEK_SET); src = (unsigned char *) opj_malloc(file_length); fread(src, 1, file_length, fsrc); fclose(fsrc); /*printf("C: %d bytes read from file\n",file_length);*/ } else { /* Preparing the transfer of the codestream from Java to C*/ /*printf("C: before transfering codestream\n");*/ fid = (*env)->GetFieldID(env, cls,"compressedStream", "[B"); jba = (*env)->GetObjectField(env, obj, fid); file_length = (*env)->GetArrayLength(env, jba); jbBody = (*env)->GetByteArrayElements(env, jba, &isCopy); src = (unsigned char*)jbBody; } /* decode the code-stream */ /* ---------------------- */ switch(parameters.decod_format) { case J2K_CFMT: { /* JPEG-2000 codestream */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_J2K); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars); /* setup the decoder decoding parameters using user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); return 1; } /* close the byte stream */ opj_cio_close(cio); } break; case JP2_CFMT: { /* JPEG 2000 compressed image data */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_JP2); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars); /* setup the decoder decoding parameters using the current image and user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); return 1; } /* close the byte stream */ opj_cio_close(cio); } break; case JPT_CFMT: { /* JPEG 2000, JPIP */ /* get a decoder handle */ dinfo = opj_create_decompress(CODEC_JPT); /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars); /* setup the decoder decoding parameters using user parameters */ opj_setup_decoder(dinfo, ¶meters); /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); if(!image) { fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); opj_cio_close(cio); return 1; } /* close the byte stream */ opj_cio_close(cio); } break; default: fprintf(stderr, "skipping file..\n"); continue; } /* free the memory containing the code-stream */ if (parameters.infile && parameters.infile[0]!='\0') { opj_free(src); } else { (*env)->ReleaseByteArrayElements(env, jba, jbBody, 0); } src = NULL; /* create output image. If the -o parameter is given in the JavaParameters, write the decoded version into a file. Implemented for debug purpose. */ /* ---------------------------------- */ switch (parameters.cod_format) { case PXM_DFMT: /* PNM PGM PPM */ if (imagetopnm(image, parameters.outfile)) { fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; case PGX_DFMT: /* PGX */ if(imagetopgx(image, parameters.outfile)){ fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; case BMP_DFMT: /* BMP */ if(imagetobmp(image, parameters.outfile)){ fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; } /* ========= Return the image to the Java structure ===============*/ #ifdef CHECK_THRESHOLDS printf("C: checking thresholds\n"); #endif /* First compute the real with and height, in function of the resolutions decoded.*/ /*wr = (image->comps[0].w + (1 << image->comps[0].factor) -1) >> image->comps[0].factor;*/ /*hr = (image->comps[0].h + (1 << image->comps[0].factor) -1) >> image->comps[0].factor;*/ w = image->comps[0].w; h = image->comps[0].h; if (image->numcomps==3) { /* 3 components color image*/ ptr = image->comps[0].data; ptr1 = image->comps[1].data; ptr2 = image->comps[2].data; #ifdef CHECK_THRESHOLDS if (image->comps[0].sgnd) { min_value = -128; max_value = 127; } else { min_value = 0; max_value = 255; } #endif /* Get the pointer to the Java structure where the data must be copied*/ fid = (*env)->GetFieldID(env, cls,"image24", "[I"); jia = (*env)->GetObjectField(env, obj, fid); jiBody = (*env)->GetIntArrayElements(env, jia, 0); ptrIBody = jiBody; printf("C: transfering image24: %d int to Java pointer=%d\n",image->numcomps*w*h, ptrIBody); for (i=0; i<w*h; i++) { tempUC = (unsigned char)(ptr[i]); tempUC1 = (unsigned char)(ptr1[i]); tempUC2 = (unsigned char)(ptr2[i]); #ifdef CHECK_THRESHOLDS if (tempUC < min_value) tempUC=min_value; else if (tempUC > max_value) tempUC=max_value; if (tempUC1 < min_value) tempUC1=min_value; else if (tempUC1 > max_value) tempUC1=max_value; if (tempUC2 < min_value) tempUC2=min_value; else if (tempUC2 > max_value) tempUC2=max_value; #endif *(ptrIBody++) = (int) ( (tempUC2<<16) + (tempUC1<<8) + tempUC ); } (*env)->ReleaseIntArrayElements(env, jia, jiBody, 0); } else { /* 1 component 8 or 16 bpp image*/ ptr = image->comps[0].data; printf("C: before transfering a %d bpp image to java (length = %d)\n",image->comps[0].prec ,w*h); if (image->comps[0].prec<=8) { fid = (*env)->GetFieldID(env, cls,"image8", "[B"); jba = (*env)->GetObjectField(env, obj, fid); jbBody = (*env)->GetByteArrayElements(env, jba, 0); ptrBBody = jbBody; #ifdef CHECK_THRESHOLDS if (image->comps[0].sgnd) { min_value = -128; max_value = 127; } else { min_value = 0; max_value = 255; } #endif /*printf("C: transfering %d shorts to Java image8 pointer = %d\n", wr*hr,ptrSBody);*/ for (i=0; i<w*h; i++) { tempUC = (unsigned char) (ptr[i]); #ifdef CHECK_THRESHOLDS if (tempUC<min_value) tempUC = min_value; else if (tempUC > max_value) tempUC = max_value; #endif *(ptrBBody++) = tempUC; } (*env)->ReleaseByteArrayElements(env, jba, jbBody, 0); printf("C: image8 transfered to Java\n"); } else { fid = (*env)->GetFieldID(env, cls,"image16", "[S"); jsa = (*env)->GetObjectField(env, obj, fid); jsBody = (*env)->GetShortArrayElements(env, jsa, 0); ptrSBody = jsBody; #ifdef CHECK_THRESHOLDS if (image->comps[0].sgnd) { min_value = -32768; max_value = 32767; } else { min_value = 0; max_value = 65535; } printf("C: minValue = %d, maxValue = %d\n", min_value, max_value); #endif printf("C: transfering %d shorts to Java image16 pointer = %d\n", w*h,ptrSBody); for (i=0; i<w*h; i++) { tempS = (short) (ptr[i]); #ifdef CHECK_THRESHOLDS if (tempS<min_value) { printf("C: value %d truncated to %d\n", tempS, min_value); tempS = min_value; } else if (tempS > max_value) { printf("C: value %d truncated to %d\n", tempS, max_value); tempS = max_value; } #endif *(ptrSBody++) = tempS; } (*env)->ReleaseShortArrayElements(env, jsa, jsBody, 0); printf("C: image16 completely filled\n"); } } /* free remaining structures */ if(dinfo) { opj_destroy_decompress(dinfo); } /* free image data structure */ opj_image_destroy(image); } return 1; /* OK */ }
int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol) { /* parse the command line */ int totlen; opj_option_t long_option[]={ {"ImgDir",REQ_ARG, NULL ,'y'}, {"OutFor",REQ_ARG, NULL ,'O'}, }; /* UniPG>> */ const char optlist[] = "i:o:r:l:hx:" #ifdef USE_JPWL "W:" #endif /* USE_JPWL */ ; /*for (i=0; i<argc; i++) { printf("[%s]",argv[i]); } printf("\n");*/ /* <<UniPG */ totlen=sizeof(long_option); img_fol->set_out_format = 0; reset_options_reading(); while (1) { int c = opj_getopt_long(argc, argv,optlist,long_option,totlen); if (c == -1) break; switch (c) { case 'i': /* input file */ { char *infile = opj_optarg; parameters->decod_format = get_file_format(infile); switch(parameters->decod_format) { case J2K_CFMT: case JP2_CFMT: case JPT_CFMT: break; default: fprintf(stderr, "!! Unrecognized format for infile : %s [accept only *.j2k, *.jp2, *.jpc or *.jpt] !!\n\n", infile); return 1; } strncpy(parameters->infile, infile, sizeof(parameters->infile)-1); } break; /* ----------------------------------------------------- */ case 'o': /* output file */ { char *outfile = opj_optarg; parameters->cod_format = get_file_format(outfile); switch(parameters->cod_format) { case PGX_DFMT: case PXM_DFMT: case BMP_DFMT: case TIF_DFMT: case RAW_DFMT: case TGA_DFMT: break; default: fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outfile); return 1; } strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1); } break; /* ----------------------------------------------------- */ case 'O': /* output format */ { char outformat[50]; char *of = opj_optarg; sprintf(outformat,".%s",of); img_fol->set_out_format = 1; parameters->cod_format = get_file_format(outformat); switch(parameters->cod_format) { case PGX_DFMT: img_fol->out_format = "pgx"; break; case PXM_DFMT: img_fol->out_format = "ppm"; break; case BMP_DFMT: img_fol->out_format = "bmp"; break; case TIF_DFMT: img_fol->out_format = "tif"; break; case RAW_DFMT: img_fol->out_format = "raw"; break; case TGA_DFMT: img_fol->out_format = "raw"; break; default: fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outformat); return 1; break; } } break; /* ----------------------------------------------------- */ case 'r': /* reduce option */ { sscanf(opj_optarg, "%d", ¶meters->cp_reduce); } break; /* ----------------------------------------------------- */ case 'l': /* layering option */ { sscanf(opj_optarg, "%d", ¶meters->cp_layer); } break; /* ----------------------------------------------------- */ case 'h': /* display an help description */ decode_help_display(); return 1; /* ------------------------------------------------------ */ case 'y': /* Image Directory path */ { img_fol->imgdirpath = (char*)opj_malloc(strlen(opj_optarg) + 1); strcpy(img_fol->imgdirpath,opj_optarg); img_fol->set_imgdir=1; } break; /* ----------------------------------------------------- */ /* UniPG>> */ #ifdef USE_JPWL case 'W': /* activate JPWL correction */ { char *token = NULL; token = strtok(opj_optarg, ","); while(token != NULL) { /* search expected number of components */ if (*token == 'c') { static int compno; compno = JPWL_EXPECTED_COMPONENTS; /* predefined no. of components */ if(sscanf(token, "c=%d", &compno) == 1) { /* Specified */ if ((compno < 1) || (compno > 256)) { fprintf(stderr, "ERROR -> invalid number of components c = %d\n", compno); return 1; } parameters->jpwl_exp_comps = compno; } else if (!strcmp(token, "c")) { /* default */ parameters->jpwl_exp_comps = compno; /* auto for default size */ } else { fprintf(stderr, "ERROR -> invalid components specified = %s\n", token); return 1; }; } /* search maximum number of tiles */ if (*token == 't') { static int tileno; tileno = JPWL_MAXIMUM_TILES; /* maximum no. of tiles */ if(sscanf(token, "t=%d", &tileno) == 1) { /* Specified */ if ((tileno < 1) || (tileno > JPWL_MAXIMUM_TILES)) { fprintf(stderr, "ERROR -> invalid number of tiles t = %d\n", tileno); return 1; } parameters->jpwl_max_tiles = tileno; } else if (!strcmp(token, "t")) { /* default */ parameters->jpwl_max_tiles = tileno; /* auto for default size */ } else { fprintf(stderr, "ERROR -> invalid tiles specified = %s\n", token); return 1; }; } /* next token or bust */ token = strtok(NULL, ","); }; parameters->jpwl_correct = true; fprintf(stdout, "JPWL correction capability activated\n"); fprintf(stdout, "- expecting %d components\n", parameters->jpwl_exp_comps); } break; #endif /* USE_JPWL */ /* <<UniPG */ /* ----------------------------------------------------- */ default: fprintf(stderr,"WARNING -> this option is not valid \"-%c %s\"\n",c, opj_optarg); break; } } /* No check for possible errors before the -i and -o options are of course not mandatory*/ return 0; }
static void jp2_apply_pclr(opj_jp2_color_t *color, opj_image_t *image, opj_common_ptr cinfo) { opj_image_comp_t *old_comps, *new_comps; unsigned char *channel_size, *channel_sign; unsigned int *entries; opj_jp2_cmap_comp_t *cmap; int *src, *dst; unsigned int j, max; unsigned short i, nr_channels, cmp, pcol; int k, top_k; channel_size = color->jp2_pclr->channel_size; channel_sign = color->jp2_pclr->channel_sign; entries = color->jp2_pclr->entries; cmap = color->jp2_pclr->cmap; nr_channels = color->jp2_pclr->nr_channels; old_comps = image->comps; new_comps = (opj_image_comp_t*) opj_malloc(nr_channels * sizeof(opj_image_comp_t)); for(i = 0; i < nr_channels; ++i) { pcol = cmap[i].pcol; cmp = cmap[i].cmp; if( pcol < nr_channels ) new_comps[pcol] = old_comps[cmp]; else { opj_event_msg(cinfo, EVT_ERROR, "Error with pcol value %d (max: %d). skipping\n", pcol, nr_channels); continue; } if(cmap[i].mtyp == 0) /* Direct use */ { old_comps[cmp].data = NULL; continue; } /* Palette mapping: */ new_comps[pcol].data = (int*) opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(int)); new_comps[pcol].prec = channel_size[i]; new_comps[pcol].sgnd = channel_sign[i]; } top_k = color->jp2_pclr->nr_entries - 1; for(i = 0; i < nr_channels; ++i) { /* Direct use: */ if(cmap[i].mtyp == 0) continue; /* Palette mapping: */ cmp = cmap[i].cmp; pcol = cmap[i].pcol; src = old_comps[cmp].data; dst = new_comps[pcol].data; max = new_comps[pcol].w * new_comps[pcol].h; for(j = 0; j < max; ++j) { /* The index */ if((k = src[j]) < 0) k = 0; else if(k > top_k) k = top_k; /* The colour */ dst[j] = entries[k * nr_channels + pcol]; } } max = image->numcomps; for(i = 0; i < max; ++i) { if(old_comps[i].data) opj_free(old_comps[i].data); } opj_free(old_comps); image->comps = new_comps; image->numcomps = nr_channels; jp2_free_pclr(color); }/* apply_pclr() */
void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image) { int i; int depth_0, sign; if(!jp2 || !parameters || !image) return; /* setup the J2K codec */ /* ------------------- */ /* Check if number of components respects standard */ if (image->numcomps < 1 || image->numcomps > 16384) { opj_event_msg(jp2->cinfo, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n"); return; } j2k_setup_encoder(jp2->j2k, parameters, image); /* setup the JP2 codec */ /* ------------------- */ /* Profile box */ jp2->brand = JP2_JP2; /* BR */ jp2->minversion = 0; /* MinV */ jp2->numcl = 1; jp2->cl = (unsigned int*) opj_malloc(jp2->numcl * sizeof(unsigned int)); jp2->cl[0] = JP2_JP2; /* CL0 : JP2 */ /* Image Header box */ jp2->numcomps = image->numcomps; /* NC */ jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t)); jp2->h = image->y1 - image->y0; /* HEIGHT */ jp2->w = image->x1 - image->x0; /* WIDTH */ /* BPC */ depth_0 = image->comps[0].prec - 1; sign = image->comps[0].sgnd; jp2->bpc = depth_0 + (sign << 7); for (i = 1; i < image->numcomps; i++) { int depth = image->comps[i].prec - 1; sign = image->comps[i].sgnd; if (depth_0 != depth) jp2->bpc = 255; } jp2->C = 7; /* C : Always 7 */ jp2->UnkC = 0; /* UnkC, colorspace specified in colr box */ jp2->IPR = 0; /* IPR, no intellectual property */ /* BitsPerComponent box */ for (i = 0; i < image->numcomps; i++) { jp2->comps[i].bpcc = image->comps[i].prec - 1 + (image->comps[i].sgnd << 7); } jp2->meth = 1; if (image->color_space == 1) jp2->enumcs = 16; /* sRGB as defined by IEC 61966-2.1 */ else if (image->color_space == 2) jp2->enumcs = 17; /* greyscale */ else if (image->color_space == 3) jp2->enumcs = 18; /* YUV */ jp2->precedence = 0; /* PRECEDENCE */ jp2->approx = 0; /* APPROX */ }
opj_pi_iterator_t *pi_initialise_encode(opj_image_t *image, opj_cp_t *cp, int tileno, J2K_T2_MODE t2_mode){ int p, q, pino; int compno, resno; int maxres = 0; int maxprec = 0; opj_pi_iterator_t *pi = NULL; opj_tcp_t *tcp = NULL; opj_tccp_t *tccp = NULL; size_t array_size; tcp = &cp->tcps[tileno]; array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t); pi = (opj_pi_iterator_t *) opj_malloc(array_size); if(!pi) { return NULL;} pi->tp_on = cp->tp_on; for(pino = 0;pino < tcp->numpocs+1 ; pino ++){ p = tileno % cp->tw; q = tileno / cp->tw; pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, image->x0); pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, image->y0); pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); pi[pino].numcomps = image->numcomps; array_size = image->numcomps * sizeof(opj_pi_comp_t); pi[pino].comps = (opj_pi_comp_t *) opj_malloc(array_size); if(!pi[pino].comps) { pi_destroy(pi, cp, tileno); return NULL; } memset(pi[pino].comps, 0, array_size); for (compno = 0; compno < pi[pino].numcomps; compno++) { int tcx0, tcy0, tcx1, tcy1; opj_pi_comp_t *comp = &pi[pino].comps[compno]; tccp = &tcp->tccps[compno]; comp->dx = image->comps[compno].dx; comp->dy = image->comps[compno].dy; comp->numresolutions = tccp->numresolutions; array_size = comp->numresolutions * sizeof(opj_pi_resolution_t); comp->resolutions = (opj_pi_resolution_t *) opj_malloc(array_size); if(!comp->resolutions) { pi_destroy(pi, cp, tileno); return NULL; } tcx0 = int_ceildiv(pi[pino].tx0, comp->dx); tcy0 = int_ceildiv(pi[pino].ty0, comp->dy); tcx1 = int_ceildiv(pi[pino].tx1, comp->dx); tcy1 = int_ceildiv(pi[pino].ty1, comp->dy); if (comp->numresolutions > maxres) { maxres = comp->numresolutions; } for (resno = 0; resno < comp->numresolutions; resno++) { int levelno; int rx0, ry0, rx1, ry1; int px0, py0, px1, py1; opj_pi_resolution_t *res = &comp->resolutions[resno]; if (tccp->csty & J2K_CCP_CSTY_PRT) { res->pdx = tccp->prcw[resno]; res->pdy = tccp->prch[resno]; } else { res->pdx = 15; res->pdy = 15; } levelno = comp->numresolutions - 1 - resno; rx0 = int_ceildivpow2(tcx0, levelno); ry0 = int_ceildivpow2(tcy0, levelno); rx1 = int_ceildivpow2(tcx1, levelno); ry1 = int_ceildivpow2(tcy1, levelno); px0 = int_floordivpow2(rx0, res->pdx) << res->pdx; py0 = int_floordivpow2(ry0, res->pdy) << res->pdy; px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx; py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy; res->pw = (rx0==rx1)?0:((px1 - px0) >> res->pdx); res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy); if (res->pw*res->ph > maxprec) { maxprec = res->pw * res->ph; } } } tccp = &tcp->tccps[0]; pi[pino].step_p = 1; pi[pino].step_c = maxprec * pi[pino].step_p; pi[pino].step_r = image->numcomps * pi[pino].step_c; pi[pino].step_l = maxres * pi[pino].step_r; for (compno = 0; compno < pi->numcomps; compno++) { opj_pi_comp_t *comp = &pi->comps[compno]; for (resno = 0; resno < comp->numresolutions; resno++) { int dx, dy; opj_pi_resolution_t *res = &comp->resolutions[resno]; dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno)); dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno)); pi[pino].dx = !pi->dx ? dx : int_min(pi->dx, dx); pi[pino].dy = !pi->dy ? dy : int_min(pi->dy, dy); } } if (pino == 0) { array_size = tcp->numlayers * pi[pino].step_l * sizeof(short int); pi[pino].include = (short int *) opj_malloc(array_size); if(!pi[pino].include) { pi_destroy(pi, cp, tileno); return NULL; } } else { pi[pino].include = pi[pino - 1].include; } /* Generation of boundaries for each prog flag*/ if(tcp->POC & (t2_mode == FINAL_PASS)){ tcp->pocs[pino].compS= tcp->pocs[pino].compno0; tcp->pocs[pino].compE= tcp->pocs[pino].compno1; tcp->pocs[pino].resS = tcp->pocs[pino].resno0; tcp->pocs[pino].resE = tcp->pocs[pino].resno1; tcp->pocs[pino].layE = tcp->pocs[pino].layno1; tcp->pocs[pino].prg = tcp->pocs[pino].prg1; if (pino > 0) tcp->pocs[pino].layS = (tcp->pocs[pino].layE > tcp->pocs[pino - 1].layE) ? tcp->pocs[pino - 1].layE : 0; }else { tcp->pocs[pino].compS= 0; tcp->pocs[pino].compE= image->numcomps; tcp->pocs[pino].resS = 0; tcp->pocs[pino].resE = maxres; tcp->pocs[pino].layS = 0; tcp->pocs[pino].layE = tcp->numlayers; tcp->pocs[pino].prg = tcp->prg; } tcp->pocs[pino].prcS = 0; tcp->pocs[pino].prcE = maxprec;; tcp->pocs[pino].txS = pi[pino].tx0; tcp->pocs[pino].txE = pi[pino].tx1; tcp->pocs[pino].tyS = pi[pino].ty0; tcp->pocs[pino].tyE = pi[pino].ty1; tcp->pocs[pino].dx = pi[pino].dx; tcp->pocs[pino].dy = pi[pino].dy; } return pi; }
opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv, int numleafsz) { int nplh[32]; int nplv[32]; int nplz[32]; opj_tgt_node_t *node = NULL; opj_tgt_node_t *parentnode = NULL; opj_tgt_node_t *parentnode0 = NULL; opj_tgt_node_t *parentnode1 = NULL; opj_tgt_tree_t *tree = NULL; int i, j, k, p, p0; int numlvls; int n, z = 0; tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t)); if(!tree) return NULL; tree->numleafsh = numleafsh; tree->numleafsv = numleafsv; tree->numleafsz = numleafsz; numlvls = 0; nplh[0] = numleafsh; nplv[0] = numleafsv; nplz[0] = numleafsz; tree->numnodes = 0; do { n = nplh[numlvls] * nplv[numlvls] * nplz[numlvls]; nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2; nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2; nplz[numlvls + 1] = (nplz[numlvls] + 1) / 2; tree->numnodes += n; ++numlvls; } while (n > 1); if (tree->numnodes == 0) { opj_free(tree); return NULL; } tree->nodes = (opj_tgt_node_t *) opj_malloc(tree->numnodes * sizeof(opj_tgt_node_t)); if(!tree->nodes) { opj_free(tree); return NULL; } node = tree->nodes; parentnode = &tree->nodes[tree->numleafsh * tree->numleafsv * tree->numleafsz]; parentnode0 = parentnode; parentnode1 = parentnode; /*fprintf(stdout,"\nH %d V %d Z %d numlvls %d nodes %d\n",tree->numleafsh,tree->numleafsv,tree->numleafsz,numlvls,tree->numnodes);*/ for (i = 0; i < numlvls - 1; ++i) { for (z = 0; z < nplz[i]; ++z) { for (j = 0; j < nplv[i]; ++j) { k = nplh[i]; while(--k >= 0) { node->parent = parentnode; /*fprintf(stdout,"node[%d].parent = node[%d]\n",n,p);*/ ++node; if(--k >= 0) { node->parent = parentnode; /*fprintf(stdout,"node[%d].parent = node[%d]\n",n,p);*/ ++node; } ++parentnode; } if((j & 1) || j == nplv[i] - 1) { parentnode0 = parentnode; } else { parentnode = parentnode0; } } if ((z & 1) || z == nplz[i] - 1) { parentnode1 = parentnode; } else { parentnode0 = parentnode1; parentnode = parentnode1; } } } node->parent = 0; tgt_reset(tree); return tree; }
opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv) { int nplh[32]; int nplv[32]; opj_tgt_node_t *node = NULL; opj_tgt_node_t *parentnode = NULL; opj_tgt_node_t *parentnode0 = NULL; opj_tgt_tree_t *tree = NULL; int i, j, k; int numlvls; int n; tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t)); if(!tree) return NULL; tree->numleafsh = numleafsh; tree->numleafsv = numleafsv; numlvls = 0; nplh[0] = numleafsh; nplv[0] = numleafsv; tree->numnodes = 0; do { n = nplh[numlvls] * nplv[numlvls]; nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2; nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2; tree->numnodes += n; ++numlvls; } while (n > 1); /* ADD */ if (tree->numnodes == 0) { opj_free(tree); return NULL; } tree->nodes = (opj_tgt_node_t *) opj_malloc(tree->numnodes * sizeof(opj_tgt_node_t)); if(!tree->nodes) { opj_free(tree); return NULL; } node = tree->nodes; parentnode = &tree->nodes[tree->numleafsh * tree->numleafsv]; parentnode0 = parentnode; for (i = 0; i < numlvls - 1; ++i) { for (j = 0; j < nplv[i]; ++j) { k = nplh[i]; while (--k >= 0) { node->parent = parentnode; ++node; if (--k >= 0) { node->parent = parentnode; ++node; } ++parentnode; } if ((j & 1) || j == nplv[i] - 1) { parentnode0 = parentnode; } else { parentnode = parentnode0; parentnode0 += nplh[i]; } } } node->parent = 0; tgt_reset(tree); return tree; }
void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno) { int tileno, compno, resno, bandno, precno, cblkno; for (tileno = 0; tileno < 1; tileno++) { opj_tcp_t *tcp = &cp->tcps[curtileno]; int j; /* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ int p = curtileno % cp->tw; int q = curtileno / cp->tw; opj_tcd_tile_t *tile = tcd->tcd_image->tiles; /* 4 borders of the tile rescale on the image if necessary */ tile->x0 = int_max(cp->tx0 + p * cp->tdx, image->x0); tile->y0 = int_max(cp->ty0 + q * cp->tdy, image->y0); tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); tile->numcomps = image->numcomps; /* tile->PPT=image->PPT; */ /* Modification of the RATE >> */ for (j = 0; j < tcp->numlayers; j++) { tcp->rates[j] = tcp->rates[j] ? int_ceildiv(tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * image->comps[0].prec, (tcp->rates[j] * 8 * image->comps[0].dx * image->comps[0].dy)) : 0; if (tcp->rates[j]) { if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) { tcp->rates[j] = tcp->rates[j - 1] + 20; } else { if (!j && tcp->rates[j] < 30) tcp->rates[j] = 30; } } } /* << Modification of the RATE */ /* tile->comps=(opj_tcd_tilecomp_t*)opj_realloc(tile->comps,image->numcomps*sizeof(opj_tcd_tilecomp_t)); */ for (compno = 0; compno < tile->numcomps; compno++) { opj_tccp_t *tccp = &tcp->tccps[compno]; opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; /* border of each tile component (global) */ tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx); tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy); tilec->x1 = int_ceildiv(tile->x1, image->comps[compno].dx); tilec->y1 = int_ceildiv(tile->y1, image->comps[compno].dy); tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * sizeof(int)); tilec->numresolutions = tccp->numresolutions; /* tilec->resolutions=(opj_tcd_resolution_t*)opj_realloc(tilec->resolutions,tilec->numresolutions*sizeof(opj_tcd_resolution_t)); */ for (resno = 0; resno < tilec->numresolutions; resno++) { int pdx, pdy; int levelno = tilec->numresolutions - 1 - resno; int tlprcxstart, tlprcystart, brprcxend, brprcyend; int tlcbgxstart, tlcbgystart, brcbgxend, brcbgyend; int cbgwidthexpn, cbgheightexpn; int cblkwidthexpn, cblkheightexpn; opj_tcd_resolution_t *res = &tilec->resolutions[resno]; /* border for each resolution level (global) */ res->x0 = int_ceildivpow2(tilec->x0, levelno); res->y0 = int_ceildivpow2(tilec->y0, levelno); res->x1 = int_ceildivpow2(tilec->x1, levelno); res->y1 = int_ceildivpow2(tilec->y1, levelno); res->numbands = resno == 0 ? 1 : 3; /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */ if (tccp->csty & J2K_CCP_CSTY_PRT) { pdx = tccp->prcw[resno]; pdy = tccp->prch[resno]; } else { pdx = 15; pdy = 15; } /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx; tlprcystart = int_floordivpow2(res->y0, pdy) << pdy; brprcxend = int_ceildivpow2(res->x1, pdx) << pdx; brprcyend = int_ceildivpow2(res->y1, pdy) << pdy; res->pw = (brprcxend - tlprcxstart) >> pdx; res->ph = (brprcyend - tlprcystart) >> pdy; if (resno == 0) { tlcbgxstart = tlprcxstart; tlcbgystart = tlprcystart; brcbgxend = brprcxend; brcbgyend = brprcyend; cbgwidthexpn = pdx; cbgheightexpn = pdy; } else { tlcbgxstart = int_ceildivpow2(tlprcxstart, 1); tlcbgystart = int_ceildivpow2(tlprcystart, 1); brcbgxend = int_ceildivpow2(brprcxend, 1); brcbgyend = int_ceildivpow2(brprcyend, 1); cbgwidthexpn = pdx - 1; cbgheightexpn = pdy - 1; } cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn); cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn); for (bandno = 0; bandno < res->numbands; bandno++) { int x0b, y0b; int gain, numbps; opj_stepsize_t *ss = NULL; opj_tcd_band_t *band = &res->bands[bandno]; band->bandno = resno == 0 ? 0 : bandno + 1; x0b = (band->bandno == 1) || (band->bandno == 3) ? 1 : 0; y0b = (band->bandno == 2) || (band->bandno == 3) ? 1 : 0; if (band->bandno == 0) { /* band border */ band->x0 = int_ceildivpow2(tilec->x0, levelno); band->y0 = int_ceildivpow2(tilec->y0, levelno); band->x1 = int_ceildivpow2(tilec->x1, levelno); band->y1 = int_ceildivpow2(tilec->y1, levelno); } else { band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelno) * x0b, levelno + 1); band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelno) * y0b, levelno + 1); band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelno) * x0b, levelno + 1); band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelno) * y0b, levelno + 1); } ss = &tccp->stepsizes[resno == 0 ? 0 : 3 * (resno - 1) + bandno + 1]; gain = tccp->qmfbid == 0 ? dwt_getgain_real(band->bandno) : dwt_getgain(band->bandno); numbps = image->comps[compno].prec + gain; band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ for (precno = 0; precno < res->pw * res->ph; precno++) { int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend; int cbgxstart = tlcbgxstart + (precno % res->pw) * (1 << cbgwidthexpn); int cbgystart = tlcbgystart + (precno / res->pw) * (1 << cbgheightexpn); int cbgxend = cbgxstart + (1 << cbgwidthexpn); int cbgyend = cbgystart + (1 << cbgheightexpn); opj_tcd_precinct_t *prc = &band->precincts[precno]; /* precinct size (global) */ prc->x0 = int_max(cbgxstart, band->x0); prc->y0 = int_max(cbgystart, band->y0); prc->x1 = int_min(cbgxend, band->x1); prc->y1 = int_min(cbgyend, band->y1); tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn; tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn; brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn; brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn; prc->cw = (brcblkxend - tlcblkxstart) >> cblkwidthexpn; prc->ch = (brcblkyend - tlcblkystart) >> cblkheightexpn; opj_free(prc->cblks); prc->cblks = (opj_tcd_cblk_t *) opj_malloc(prc->cw * prc->ch * sizeof(opj_tcd_cblk_t)); if (prc->incltree != NULL) { tgt_destroy(prc->incltree); } if (prc->imsbtree != NULL) { tgt_destroy(prc->imsbtree); } prc->incltree = tgt_create(prc->cw, prc->ch); prc->imsbtree = tgt_create(prc->cw, prc->ch); for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { int cblkxstart = tlcblkxstart + (cblkno % prc->cw) * (1 << cblkwidthexpn); int cblkystart = tlcblkystart + (cblkno / prc->cw) * (1 << cblkheightexpn); int cblkxend = cblkxstart + (1 << cblkwidthexpn); int cblkyend = cblkystart + (1 << cblkheightexpn); opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; /* code-block size (global) */ cblk->x0 = int_max(cblkxstart, prc->x0); cblk->y0 = int_max(cblkystart, prc->y0); cblk->x1 = int_min(cblkxend, prc->x1); cblk->y1 = int_min(cblkyend, prc->y1); } } /* precno */ } /* bandno */ } /* resno */ } /* compno */ } /* tileno */ /* tcd_dump(stdout, tcd, &tcd->tcd_image); */ }
static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_iterator_t *pi, unsigned char *dest, int length, opj_image_info_t * image_info, int tileno) { int bandno, cblkno; unsigned char *sop = 0, *eph = 0; unsigned char *c = dest; int compno = pi->compno; /* component value */ int resno = pi->resno; /* resolution level value */ int precno = pi->precno; /* precinct value */ int layno = pi->layno; /* quality layer value */ opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; opj_tcd_resolution_t *res = &tilec->resolutions[resno]; opj_bio_t *bio = NULL; /* BIO component */ /* <SOP 0xff91> */ if (tcp->csty & J2K_CP_CSTY_SOP) { sop = (unsigned char *) opj_malloc(6 * sizeof(unsigned char)); sop[0] = 255; sop[1] = 145; sop[2] = 0; sop[3] = 4; sop[4] = (image_info->num % 65536) / 256; sop[5] = (image_info->num % 65536) % 256; memcpy(c, sop, 6); opj_free(sop); c += 6; } /* </SOP> */ if (!layno) { for (bandno = 0; bandno < res->numbands; bandno++) { opj_tcd_band_t *band = &res->bands[bandno]; opj_tcd_precinct_t *prc = &band->precincts[precno]; tgt_reset(prc->incltree); tgt_reset(prc->imsbtree); for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; cblk->numpasses = 0; tgt_setvalue(prc->imsbtree, cblkno, band->numbps - cblk->numbps); } } } bio = bio_create(); bio_init_enc(bio, c, length); bio_write(bio, 1, 1); /* Empty header bit */ /* Writing Packet header */ for (bandno = 0; bandno < res->numbands; bandno++) { opj_tcd_band_t *band = &res->bands[bandno]; opj_tcd_precinct_t *prc = &band->precincts[precno]; for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; opj_tcd_layer_t *layer = &cblk->layers[layno]; if (!cblk->numpasses && layer->numpasses) { tgt_setvalue(prc->incltree, cblkno, layno); } } for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; opj_tcd_layer_t *layer = &cblk->layers[layno]; int increment = 0; int nump = 0; int len = 0, passno; /* cblk inclusion bits */ if (!cblk->numpasses) { tgt_encode(bio, prc->incltree, cblkno, layno + 1); } else { bio_write(bio, layer->numpasses != 0, 1); } /* if cblk not included, go to the next cblk */ if (!layer->numpasses) { continue; } /* if first instance of cblk --> zero bit-planes information */ if (!cblk->numpasses) { cblk->numlenbits = 3; tgt_encode(bio, prc->imsbtree, cblkno, 999); } /* number of coding passes included */ t2_putnumpasses(bio, layer->numpasses); /* computation of the increase of the length indicator and insertion in the header */ for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) { opj_tcd_pass_t *pass = &cblk->passes[passno]; nump++; len += pass->len; if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) { increment = int_max(increment, int_floorlog2(len) + 1 - (cblk->numlenbits + int_floorlog2(nump))); len = 0; nump = 0; } } t2_putcommacode(bio, increment); /* computation of the new Length indicator */ cblk->numlenbits += increment; /* insertion of the codeword segment length */ for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) { opj_tcd_pass_t *pass = &cblk->passes[passno]; nump++; len += pass->len; if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) { bio_write(bio, len, cblk->numlenbits + int_floorlog2(nump)); len = 0; nump = 0; } } } } if (bio_flush(bio)) { return -999; /* modified to eliminate longjmp !! */ } c += bio_numbytes(bio); bio_destroy(bio); /* <EPH 0xff92> */ if (tcp->csty & J2K_CP_CSTY_EPH) { eph = (unsigned char *) opj_malloc(2 * sizeof(unsigned char)); eph[0] = 255; eph[1] = 146; memcpy(c, eph, 2); opj_free(eph); c += 2; } /* </EPH> */ /* Writing the packet body */ for (bandno = 0; bandno < res->numbands; bandno++) { opj_tcd_band_t *band = &res->bands[bandno]; opj_tcd_precinct_t *prc = &band->precincts[precno]; for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; opj_tcd_layer_t *layer = &cblk->layers[layno]; if (!layer->numpasses) { continue; } if (c + layer->len > dest + length) { return -999; } memcpy(c, layer->data, layer->len); cblk->numpasses += layer->numpasses; c += layer->len; /* ADD for index Cfr. Marcela --> delta disto by packet */ if(image_info && image_info->index_write && image_info->index_on) { opj_tile_info_t *info_TL = &image_info->tile[tileno]; opj_packet_info_t *info_PK = &info_TL->packet[image_info->num]; info_PK->disto += layer->disto; if (image_info->D_max < info_PK->disto) { image_info->D_max = info_PK->disto; } } /* </ADD> */ } } return (c - dest); }
opj_pi_iterator_t *pi_create(opj_volume_t *volume, opj_cp_t *cp, int tileno) { int p, q, r; int compno, resno, pino; opj_pi_iterator_t *pi = NULL; opj_tcp_t *tcp = NULL; opj_tccp_t *tccp = NULL; size_t array_size; tcp = &cp->tcps[tileno]; array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t); pi = (opj_pi_iterator_t *) opj_malloc(array_size); if(!pi) { fprintf(stdout,"[ERROR] Malloc of opj_pi_iterator failed \n"); return NULL; } for (pino = 0; pino < tcp->numpocs + 1; pino++) { /* change */ int maxres = 0; int maxprec = 0; p = tileno % cp->tw; q = tileno / cp->tw; r = tileno / (cp->tw * cp->th); pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, volume->x0); pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, volume->y0); pi[pino].tz0 = int_max(cp->tz0 + r * cp->tdz, volume->z0); pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1); pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1); pi[pino].tz1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1); pi[pino].numcomps = volume->numcomps; array_size = volume->numcomps * sizeof(opj_pi_comp_t); pi[pino].comps = (opj_pi_comp_t *) opj_malloc(array_size); if(!pi[pino].comps) { fprintf(stdout,"[ERROR] Malloc of opj_pi_comp failed \n"); pi_destroy(pi, cp, tileno); return NULL; } memset(pi[pino].comps, 0, array_size); for (compno = 0; compno < pi->numcomps; compno++) { int tcx0, tcx1, tcy0, tcy1, tcz0, tcz1; int i; opj_pi_comp_t *comp = &pi[pino].comps[compno]; tccp = &tcp->tccps[compno]; comp->dx = volume->comps[compno].dx; comp->dy = volume->comps[compno].dy; comp->dz = volume->comps[compno].dz; for (i = 0; i < 3; i++) { comp->numresolution[i] = tccp->numresolution[i]; if (comp->numresolution[i] > maxres) { maxres = comp->numresolution[i]; } } array_size = comp->numresolution[0] * sizeof(opj_pi_resolution_t); comp->resolutions = (opj_pi_resolution_t *) opj_malloc(array_size); if(!comp->resolutions) { fprintf(stdout,"[ERROR] Malloc of opj_pi_resolution failed \n"); pi_destroy(pi, cp, tileno); return NULL; } tcx0 = int_ceildiv(pi->tx0, comp->dx); tcy0 = int_ceildiv(pi->ty0, comp->dy); tcz0 = int_ceildiv(pi->tz0, comp->dz); tcx1 = int_ceildiv(pi->tx1, comp->dx); tcy1 = int_ceildiv(pi->ty1, comp->dy); tcz1 = int_ceildiv(pi->tz1, comp->dz); for (resno = 0; resno < comp->numresolution[0]; resno++) { int levelnox, levelnoy, levelnoz, diff; int rx0, ry0, rz0, rx1, ry1, rz1; int px0, py0, pz0, px1, py1, pz1; opj_pi_resolution_t *res = &comp->resolutions[resno]; if (tccp->csty & J3D_CCP_CSTY_PRT) { res->pdx = tccp->prctsiz[0][resno]; res->pdy = tccp->prctsiz[1][resno]; res->pdz = tccp->prctsiz[2][resno]; } else { res->pdx = 15; res->pdy = 15; res->pdz = 15; } levelnox = comp->numresolution[0] - 1 - resno; levelnoy = comp->numresolution[1] - 1 - resno; levelnoz = comp->numresolution[2] - 1 - resno; if (levelnoz < 0) levelnoz = 0; diff = comp->numresolution[0] - comp->numresolution[2]; rx0 = int_ceildivpow2(tcx0, levelnox); ry0 = int_ceildivpow2(tcy0, levelnoy); rz0 = int_ceildivpow2(tcz0, levelnoz); rx1 = int_ceildivpow2(tcx1, levelnox); ry1 = int_ceildivpow2(tcy1, levelnoy); rz1 = int_ceildivpow2(tcz1, levelnoz); px0 = int_floordivpow2(rx0, res->pdx) << res->pdx; py0 = int_floordivpow2(ry0, res->pdy) << res->pdy; pz0 = int_floordivpow2(rz0, res->pdz) << res->pdz; px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx; py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy; pz1 = int_ceildivpow2(rz1, res->pdz) << res->pdz; res->prctno[0] = (rx0==rx1)? 0 : ((px1 - px0) >> res->pdx); res->prctno[1] = (ry0==ry1)? 0 : ((py1 - py0) >> res->pdy); res->prctno[2] = (rz0==rz1)? 0 : ((pz1 - pz0) >> res->pdz); if (res->prctno[0]*res->prctno[1]*res->prctno[2] > maxprec) { maxprec = res->prctno[0]*res->prctno[1]*res->prctno[2]; } } } tccp = &tcp->tccps[0]; pi[pino].step_p = 1; pi[pino].step_c = maxprec * pi[pino].step_p; pi[pino].step_r = volume->numcomps * pi[pino].step_c; pi[pino].step_l = maxres * pi[pino].step_r; if (pino == 0) { array_size = volume->numcomps * maxres * tcp->numlayers * maxprec * sizeof(short int); pi[pino].include = (short int *) opj_malloc(array_size); if(!pi[pino].include) { fprintf(stdout,"[ERROR] Malloc of pi[pino].include failed \n"); pi_destroy(pi, cp, tileno); return NULL; } } else { pi[pino].include = pi[pino - 1].include; } if (tcp->POC == 0) { pi[pino].first = 1; pi[pino].poc.resno0 = 0; pi[pino].poc.compno0 = 0; pi[pino].poc.layno1 = tcp->numlayers; pi[pino].poc.resno1 = maxres; pi[pino].poc.compno1 = volume->numcomps; pi[pino].poc.prg = tcp->prg; } else { pi[pino].first = 1; pi[pino].poc.resno0 = tcp->pocs[pino].resno0; pi[pino].poc.compno0 = tcp->pocs[pino].compno0; pi[pino].poc.layno1 = tcp->pocs[pino].layno1; pi[pino].poc.resno1 = tcp->pocs[pino].resno1; pi[pino].poc.compno1 = tcp->pocs[pino].compno1; pi[pino].poc.prg = tcp->pocs[pino].prg; } } return pi; }
opj_image_t* opj_image_create0(void) { opj_image_t *image = (opj_image_t*)opj_malloc(sizeof(opj_image_t)); memset(image,0,sizeof(opj_image_t)); return image; }
void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) { int tileno, compno, resno, bandno, precno, cblkno, i, j, p, q; unsigned int x0 = 0, y0 = 0, x1 = 0, y1 = 0, w, h; tcd->image = image; tcd->cp = cp; tcd->tcd_image->tw = cp->tw; tcd->tcd_image->th = cp->th; tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tcd_tile_t)); for (i = 0; i < cp->tileno_size; i++) { opj_tcp_t *tcp = &(cp->tcps[cp->tileno[i]]); opj_tcd_tile_t *tile = &(tcd->tcd_image->tiles[cp->tileno[i]]); /* cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ tileno = cp->tileno[i]; p = tileno % cp->tw; /* si numerotation matricielle .. */ q = tileno / cp->tw; /* .. coordonnees de la tile (q,p) q pour ligne et p pour colonne */ /* 4 borders of the tile rescale on the image if necessary */ tile->x0 = int_max(cp->tx0 + p * cp->tdx, image->x0); tile->y0 = int_max(cp->ty0 + q * cp->tdy, image->y0); tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); tile->numcomps = image->numcomps; tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(image->numcomps * sizeof(opj_tcd_tilecomp_t)); for (compno = 0; compno < tile->numcomps; compno++) { opj_tccp_t *tccp = &tcp->tccps[compno]; opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; /* border of each tile component (global) */ tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx); tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy); tilec->x1 = int_ceildiv(tile->x1, image->comps[compno].dx); tilec->y1 = int_ceildiv(tile->y1, image->comps[compno].dy); tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * sizeof(int)); tilec->numresolutions = tccp->numresolutions; tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(tilec->numresolutions * sizeof(opj_tcd_resolution_t)); for (resno = 0; resno < tilec->numresolutions; resno++) { int pdx, pdy; int levelno = tilec->numresolutions - 1 - resno; int tlprcxstart, tlprcystart, brprcxend, brprcyend; int tlcbgxstart, tlcbgystart, brcbgxend, brcbgyend; int cbgwidthexpn, cbgheightexpn; int cblkwidthexpn, cblkheightexpn; opj_tcd_resolution_t *res = &tilec->resolutions[resno]; /* border for each resolution level (global) */ res->x0 = int_ceildivpow2(tilec->x0, levelno); res->y0 = int_ceildivpow2(tilec->y0, levelno); res->x1 = int_ceildivpow2(tilec->x1, levelno); res->y1 = int_ceildivpow2(tilec->y1, levelno); res->numbands = resno == 0 ? 1 : 3; /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */ if (tccp->csty & J2K_CCP_CSTY_PRT) { pdx = tccp->prcw[resno]; pdy = tccp->prch[resno]; } else { pdx = 15; pdy = 15; } /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx; tlprcystart = int_floordivpow2(res->y0, pdy) << pdy; brprcxend = int_ceildivpow2(res->x1, pdx) << pdx; brprcyend = int_ceildivpow2(res->y1, pdy) << pdy; res->pw = (res->x0 == res->x1) ? 0 : ((brprcxend - tlprcxstart) >> pdx); res->ph = (res->y0 == res->y1) ? 0 : ((brprcyend - tlprcystart) >> pdy); if (resno == 0) { tlcbgxstart = tlprcxstart; tlcbgystart = tlprcystart; brcbgxend = brprcxend; brcbgyend = brprcyend; cbgwidthexpn = pdx; cbgheightexpn = pdy; } else { tlcbgxstart = int_ceildivpow2(tlprcxstart, 1); tlcbgystart = int_ceildivpow2(tlprcystart, 1); brcbgxend = int_ceildivpow2(brprcxend, 1); brcbgyend = int_ceildivpow2(brprcyend, 1); cbgwidthexpn = pdx - 1; cbgheightexpn = pdy - 1; } cblkwidthexpn = int_min(tccp->cblkw, cbgwidthexpn); cblkheightexpn = int_min(tccp->cblkh, cbgheightexpn); for (bandno = 0; bandno < res->numbands; bandno++) { int x0b, y0b; int gain, numbps; opj_stepsize_t *ss = NULL; opj_tcd_band_t *band = &res->bands[bandno]; band->bandno = resno == 0 ? 0 : bandno + 1; x0b = (band->bandno == 1) || (band->bandno == 3) ? 1 : 0; y0b = (band->bandno == 2) || (band->bandno == 3) ? 1 : 0; if (band->bandno == 0) { /* band border (global) */ band->x0 = int_ceildivpow2(tilec->x0, levelno); band->y0 = int_ceildivpow2(tilec->y0, levelno); band->x1 = int_ceildivpow2(tilec->x1, levelno); band->y1 = int_ceildivpow2(tilec->y1, levelno); } else { /* band border (global) */ band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelno) * x0b, levelno + 1); band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelno) * y0b, levelno + 1); band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelno) * x0b, levelno + 1); band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelno) * y0b, levelno + 1); } ss = &tccp->stepsizes[resno == 0 ? 0 : 3 * (resno - 1) + bandno + 1]; gain = tccp->qmfbid == 0 ? dwt_getgain_real(band->bandno) : dwt_getgain(band->bandno); numbps = image->comps[compno].prec + gain; band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ band->precincts = (opj_tcd_precinct_t *) opj_malloc(res->pw * res->ph * sizeof(opj_tcd_precinct_t)); for (precno = 0; precno < res->pw * res->ph; precno++) { int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend; int cbgxstart = tlcbgxstart + (precno % res->pw) * (1 << cbgwidthexpn); int cbgystart = tlcbgystart + (precno / res->pw) * (1 << cbgheightexpn); int cbgxend = cbgxstart + (1 << cbgwidthexpn); int cbgyend = cbgystart + (1 << cbgheightexpn); opj_tcd_precinct_t *prc = &band->precincts[precno]; /* precinct size (global) */ prc->x0 = int_max(cbgxstart, band->x0); prc->y0 = int_max(cbgystart, band->y0); prc->x1 = int_min(cbgxend, band->x1); prc->y1 = int_min(cbgyend, band->y1); tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn; tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn; brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn; brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn; prc->cw = (brcblkxend - tlcblkxstart) >> cblkwidthexpn; prc->ch = (brcblkyend - tlcblkystart) >> cblkheightexpn; prc->cblks = (opj_tcd_cblk_t *) opj_malloc(prc->cw * prc->ch * sizeof(opj_tcd_cblk_t)); prc->incltree = tgt_create(prc->cw, prc->ch); prc->imsbtree = tgt_create(prc->cw, prc->ch); for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { int cblkxstart = tlcblkxstart + (cblkno % prc->cw) * (1 << cblkwidthexpn); int cblkystart = tlcblkystart + (cblkno / prc->cw) * (1 << cblkheightexpn); int cblkxend = cblkxstart + (1 << cblkwidthexpn); int cblkyend = cblkystart + (1 << cblkheightexpn); /* code-block size (global) */ opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; cblk->x0 = int_max(cblkxstart, prc->x0); cblk->y0 = int_max(cblkystart, prc->y0); cblk->x1 = int_min(cblkxend, prc->x1); cblk->y1 = int_min(cblkyend, prc->y1); } } /* precno */ } /* bandno */ } /* resno */ } /* compno */ } /* i = 0..cp->tileno_size */ /* tcd_dump(stdout, tcd, &tcd->tcd_image); */ /* Allocate place to store the decoded data = final image Place limited by the tile really present in the codestream */ for (i = 0; i < image->numcomps; i++) { for (j = 0; j < cp->tileno_size; j++) { tileno = cp->tileno[j]; x0 = j == 0 ? tcd->tcd_image->tiles[tileno].comps[i].x0 : int_min(x0, (unsigned int) tcd->tcd_image->tiles[tileno].comps[i].x0); y0 = j == 0 ? tcd->tcd_image->tiles[tileno].comps[i].y0 : int_min(y0, (unsigned int) tcd->tcd_image->tiles[tileno].comps[i].y0); x1 = j == 0 ? tcd->tcd_image->tiles[tileno].comps[i].x1 : int_max(x1, (unsigned int) tcd->tcd_image->tiles[tileno].comps[i].x1); y1 = j == 0 ? tcd->tcd_image->tiles[tileno].comps[i].y1 : int_max(y1, (unsigned int) tcd->tcd_image->tiles[tileno].comps[i].y1); } w = x1 - x0; h = y1 - y0; image->comps[i].data = (int *) opj_malloc(w * h * sizeof(int)); image->comps[i].w = w; image->comps[i].h = h; image->comps[i].x0 = x0; image->comps[i].y0 = y0; } }
opj_bio_t* bio_create(void) { opj_bio_t *bio = (opj_bio_t*)opj_malloc(sizeof(opj_bio_t)); return bio; }
opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv) { OPJ_INT32 nplh[32]; OPJ_INT32 nplv[32]; opj_tgt_node_t *node = 00; opj_tgt_node_t *l_parent_node = 00; opj_tgt_node_t *l_parent_node0 = 00; opj_tgt_tree_t *tree = 00; OPJ_UINT32 i; OPJ_INT32 j,k; OPJ_UINT32 numlvls; OPJ_UINT32 n; tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t)); if(!tree) { fprintf(stderr, "ERROR in tgt_create while allocating tree\n"); return 00; } memset(tree,0,sizeof(opj_tgt_tree_t)); tree->numleafsh = numleafsh; tree->numleafsv = numleafsv; numlvls = 0; nplh[0] = (OPJ_INT32)numleafsh; nplv[0] = (OPJ_INT32)numleafsv; tree->numnodes = 0; do { n = (OPJ_UINT32)(nplh[numlvls] * nplv[numlvls]); nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2; nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2; tree->numnodes += n; ++numlvls; } while (n > 1); /* ADD */ if (tree->numnodes == 0) { opj_free(tree); fprintf(stderr, "WARNING in tgt_create tree->numnodes == 0, no tree created.\n"); return 00; } tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes, sizeof(opj_tgt_node_t)); if(!tree->nodes) { fprintf(stderr, "ERROR in tgt_create while allocating node of the tree\n"); opj_free(tree); return 00; } memset(tree->nodes,0,tree->numnodes * sizeof(opj_tgt_node_t)); tree->nodes_size = tree->numnodes * (OPJ_UINT32)sizeof(opj_tgt_node_t); node = tree->nodes; l_parent_node = &tree->nodes[tree->numleafsh * tree->numleafsv]; l_parent_node0 = l_parent_node; for (i = 0; i < numlvls - 1; ++i) { for (j = 0; j < nplv[i]; ++j) { k = nplh[i]; while (--k >= 0) { node->parent = l_parent_node; ++node; if (--k >= 0) { node->parent = l_parent_node; ++node; } ++l_parent_node; } if ((j & 1) || j == nplv[i] - 1) { l_parent_node0 = l_parent_node; } else { l_parent_node = l_parent_node0; l_parent_node0 += nplh[i]; } } } node->parent = 0; opj_tgt_reset(tree); return tree; }
opj_pi_iterator_t *pi_create_decode(opj_image_t *image, opj_cp_t *cp, int tileno) { int p, q; int compno, resno, pino; opj_pi_iterator_t *pi = NULL; opj_tcp_t *tcp = NULL; opj_tccp_t *tccp = NULL; size_t array_size; tcp = &cp->tcps[tileno]; array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t); pi = (opj_pi_iterator_t *) opj_malloc(array_size); if(!pi) { /* TODO: throw an error */ return NULL; } for (pino = 0; pino < tcp->numpocs + 1; pino++) { /* change */ int maxres = 0; int maxprec = 0; p = tileno % cp->tw; q = tileno / cp->tw; pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, image->x0); pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, image->y0); pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); pi[pino].numcomps = image->numcomps; array_size = image->numcomps * sizeof(opj_pi_comp_t); pi[pino].comps = (opj_pi_comp_t *) opj_malloc(array_size); if(!pi[pino].comps) { /* TODO: throw an error */ pi_destroy(pi, cp, tileno); return NULL; } memset(pi[pino].comps, 0, array_size); for (compno = 0; compno < pi->numcomps; compno++) { int tcx0, tcy0, tcx1, tcy1; opj_pi_comp_t *comp = &pi[pino].comps[compno]; tccp = &tcp->tccps[compno]; comp->dx = image->comps[compno].dx; comp->dy = image->comps[compno].dy; comp->numresolutions = tccp->numresolutions; array_size = comp->numresolutions * sizeof(opj_pi_resolution_t); comp->resolutions = (opj_pi_resolution_t *) opj_malloc(array_size); if(!comp->resolutions) { /* TODO: throw an error */ pi_destroy(pi, cp, tileno); return NULL; } tcx0 = int_ceildiv(pi->tx0, comp->dx); tcy0 = int_ceildiv(pi->ty0, comp->dy); tcx1 = int_ceildiv(pi->tx1, comp->dx); tcy1 = int_ceildiv(pi->ty1, comp->dy); if (comp->numresolutions > maxres) { maxres = comp->numresolutions; } for (resno = 0; resno < comp->numresolutions; resno++) { int levelno; int rx0, ry0, rx1, ry1; int px0, py0, px1, py1; opj_pi_resolution_t *res = &comp->resolutions[resno]; if (tccp->csty & J2K_CCP_CSTY_PRT) { res->pdx = tccp->prcw[resno]; res->pdy = tccp->prch[resno]; } else { res->pdx = 15; res->pdy = 15; } levelno = comp->numresolutions - 1 - resno; rx0 = int_ceildivpow2(tcx0, levelno); ry0 = int_ceildivpow2(tcy0, levelno); rx1 = int_ceildivpow2(tcx1, levelno); ry1 = int_ceildivpow2(tcy1, levelno); px0 = int_floordivpow2(rx0, res->pdx) << res->pdx; py0 = int_floordivpow2(ry0, res->pdy) << res->pdy; px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx; py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy; res->pw = (rx0==rx1)?0:((px1 - px0) >> res->pdx); res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy); if (res->pw*res->ph > maxprec) { maxprec = res->pw*res->ph; } } } tccp = &tcp->tccps[0]; pi[pino].step_p = 1; pi[pino].step_c = maxprec * pi[pino].step_p; pi[pino].step_r = image->numcomps * pi[pino].step_c; pi[pino].step_l = maxres * pi[pino].step_r; if (pino == 0) { array_size = image->numcomps * maxres * tcp->numlayers * maxprec * sizeof(short int); pi[pino].include = (short int *) opj_malloc(array_size); if(!pi[pino].include) { /* TODO: throw an error */ pi_destroy(pi, cp, tileno); return NULL; } } else { pi[pino].include = pi[pino - 1].include; } if (tcp->POC == 0) { pi[pino].first = 1; pi[pino].poc.resno0 = 0; pi[pino].poc.compno0 = 0; pi[pino].poc.layno1 = tcp->numlayers; pi[pino].poc.resno1 = maxres; pi[pino].poc.compno1 = image->numcomps; pi[pino].poc.prg = tcp->prg; } else { pi[pino].first = 1; pi[pino].poc.resno0 = tcp->pocs[pino].resno0; pi[pino].poc.compno0 = tcp->pocs[pino].compno0; pi[pino].poc.layno1 = tcp->pocs[pino].layno1; pi[pino].poc.resno1 = tcp->pocs[pino].resno1; pi[pino].poc.compno1 = tcp->pocs[pino].compno1; pi[pino].poc.prg = tcp->pocs[pino].prg; } pi[pino].poc.layno0 = 0; pi[pino].poc.precno0 = 0; pi[pino].poc.precno1 = maxprec; } return pi; }
OPJ_BOOL opj_thread_pool_submit_job(opj_thread_pool_t* tp, opj_job_fn job_fn, void* user_data) { opj_worker_thread_job_t* job; opj_job_list_t* item; if( tp->mutex == NULL ) { job_fn( user_data, tp->tls ); return OPJ_TRUE; } job = (opj_worker_thread_job_t*)opj_malloc(sizeof(opj_worker_thread_job_t)); if( job == NULL ) return OPJ_FALSE; job->job_fn = job_fn; job->user_data = user_data; item = (opj_job_list_t*) opj_malloc(sizeof(opj_job_list_t)); if( item == NULL ) { opj_free(job); return OPJ_FALSE; } item->job = job; opj_mutex_lock(tp->mutex); tp->signaling_threshold = 100 * tp->worker_threads_count; while( tp->pending_jobs_count > tp->signaling_threshold ) { /* printf("%d jobs enqueued. Waiting\n", tp->pending_jobs_count); */ opj_cond_wait(tp->cond, tp->mutex); /* printf("...%d jobs enqueued.\n", tp->pending_jobs_count); */ } item->next = tp->job_queue; tp->job_queue = item; tp->pending_jobs_count ++; if( tp->waiting_worker_thread_list ) { opj_worker_thread_t* worker_thread; opj_worker_thread_list_t* next; opj_worker_thread_list_t* to_opj_free; worker_thread = tp->waiting_worker_thread_list->worker_thread; assert( worker_thread->marked_as_waiting ); worker_thread->marked_as_waiting = OPJ_FALSE; next = tp->waiting_worker_thread_list->next; to_opj_free = tp->waiting_worker_thread_list; tp->waiting_worker_thread_list = next; tp->waiting_worker_thread_count --; opj_mutex_lock(worker_thread->mutex); opj_mutex_unlock(tp->mutex); opj_cond_signal(worker_thread->cond); opj_mutex_unlock(worker_thread->mutex); opj_free(to_opj_free); } else opj_mutex_unlock(tp->mutex); return OPJ_TRUE; }