7a5d177dc67f22921d1f2158f17cc312cc0591d1
[openjpeg.git] / codec / convert.c
1 /*
2  * Copyright (c) 2001-2003, David Janssens
3  * Copyright (c) 2002-2003, Yannick Verschueren
4  * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
5  * Copyright (c) 2005, Herve Drolon, FreeImage Team
6  * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
7  * Copyright (c) 2006, M�nica D�ez Garc�a, Image Processing Laboratory, University of Valladolid, Spain
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include "../libjp3dvm/openjpeg3d.h"
35 #ifdef _WIN32
36 #include "windirent.h"
37 #else
38 #include <dirent.h>
39 #endif /* _WIN32 */
40
41
42
43 void dump_volume(FILE *fd, opj_volume_t * vol) {
44         int compno;
45         fprintf(fd, "volume {\n");
46         fprintf(fd, "  x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d\n", vol->x0, vol->y0, vol->z0,vol->x1, vol->y1,  vol->z1);
47         fprintf(fd, "  numcomps=%d\n", vol->numcomps);
48         for (compno = 0; compno < vol->numcomps; compno++) {
49                 opj_volume_comp_t *comp = &vol->comps[compno];
50                 fprintf(fd, "  comp %d {\n", compno);
51                 fprintf(fd, "    dx=%d, dy=%d, dz=%d\n", comp->dx, comp->dy, comp->dz);
52                 fprintf(fd, "    prec=%d\n", comp->prec);
53                 fprintf(fd, "    sgnd=%d\n", comp->sgnd);
54                 fprintf(fd, "  }\n");
55         }
56         fprintf(fd, "}\n");
57 }
58
59 /*
60  * Get logarithm of an integer and round downwards.
61  *
62  * log2(a)
63  */
64 static int int_floorlog2(int a) {
65         int l;
66         for (l = 0; a > 1; l++) {
67                 a >>= 1;
68         }
69         return l;
70 }
71
72 /*
73  * Divide an integer by a power of 2 and round upwards.
74  *
75  * a divided by 2^b
76  */
77 static int int_ceildivpow2(int a, int b) {
78         return (a + (1 << b) - 1) >> b;
79 }
80
81 /*
82  * Divide an integer and round upwards.
83  *
84  * a divided by b
85  */
86 static int int_ceildiv(int a, int b) {
87         return (a + b - 1) / b;
88 }
89
90
91 /* -->> -->> -->> -->>
92
93 PGX IMAGE FORMAT
94
95 <<-- <<-- <<-- <<-- */
96
97
98 unsigned char readuchar(FILE * f)
99 {
100   unsigned char c1;
101   fread(&c1, 1, 1, f);
102   return c1;
103 }
104
105 unsigned short readushort(FILE * f, int bigendian)
106 {
107   unsigned char c1, c2;
108   fread(&c1, 1, 1, f);
109   fread(&c2, 1, 1, f);
110   if (bigendian)
111     return (c1 << 8) + c2;
112   else
113     return (c2 << 8) + c1;
114 }
115
116 unsigned int readuint(FILE * f, int bigendian)
117 {
118   unsigned char c1, c2, c3, c4;
119   fread(&c1, 1, 1, f);
120   fread(&c2, 1, 1, f);
121   fread(&c3, 1, 1, f);
122   fread(&c4, 1, 1, f);
123   if (bigendian)
124     return (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
125   else
126     return (c4 << 24) + (c3 << 16) + (c2 << 8) + c1;
127 }
128 /*****************************************/
129 static unsigned short ShortSwap(unsigned short v)
130 {
131   unsigned char c1, c2;
132   c1 = v & 0xff;
133   c2 = (v >> 8) & 0xff;
134   return (c1 << 8) + c2;
135 }
136
137 static unsigned int LongSwap (unsigned int i)
138 {
139   unsigned char b1, b2, b3, b4;
140   b1 = i & 255;
141   b2 = ( i >> 8 ) & 255;
142   b3 = ( i>>16 ) & 255;
143   b4 = ( i>>24 ) & 255;
144   return ((int)b1 << 24) + ((int)b2 << 16) + ((int)b3 << 8) + b4;
145 }
146 /*****************************************/
147
148 opj_volume_t* pgxtovolume(char *relpath, opj_cparameters_t *parameters) {
149         
150         FILE *f = NULL;
151         int w, h, prec;
152         unsigned long offset;
153         int i, s, numcomps, maxvalue, sliceno, slicepos, maxslice = 0;
154         
155         OPJ_COLOR_SPACE color_space;
156         opj_volume_cmptparm_t cmptparm; // maximum of 1 component 
157         opj_volume_t * volume = NULL;
158
159         char endian1,endian2,sign;
160         char signtmp[32];
161         char temp[32];
162         opj_volume_comp_t *comp = NULL;
163
164                 DIR *dirp;
165     struct dirent *direntp;
166         
167         char *tmp = NULL, *tmp2 = NULL,
168                 *point = NULL, *pgx = NULL;
169         char tmpdirpath[MAX_PATH];
170         char dirpath[MAX_PATH];
171         char pattern[MAX_PATH];
172         char pgxfiles[MAX_SLICES][MAX_PATH];
173         int pgxslicepos[MAX_SLICES];
174         char tmpno[3];
175         
176         numcomps = 1;
177         color_space = CLRSPC_GRAY;
178         sliceno = 0;
179         maxvalue = 0;
180         memset(pgxfiles, 0, MAX_SLICES * MAX_PATH * sizeof(char));
181         memset(&cmptparm, 0, sizeof(opj_volume_cmptparm_t));
182         
183         /* Separaci�n del caso de un �nico slice frente al de muchos */
184         if ((tmp = strrchr(relpath,'-')) == NULL){ 
185                 //fprintf(stdout,"[INFO] A volume of only one slice....\n");
186                 sliceno = 1;
187                 maxslice = 1;
188                 strcpy(pgxfiles[0],relpath);
189         
190         } else {
191                 //Fetch only the path 
192                 strcpy(tmpdirpath,relpath);
193                 if ((tmp = strrchr(tmpdirpath,'/')) != NULL){
194                         tmp++; *tmp='\0';
195                         strcpy(dirpath,tmpdirpath);
196                 } else {
197                         strcpy(dirpath,"./");
198                 }
199
200                 //Fetch the pattern of the volume slices
201                 if ((tmp = strrchr (relpath,'/')) != NULL) 
202                         tmp++;  
203                 else 
204                         tmp = relpath;
205         if ((tmp2 = strrchr(tmp,'-')) != NULL)
206             *tmp2='\0';
207                 else{ 
208                         fprintf(stdout, "[ERROR] tmp2 ha dado null. no ha encontrado el * %s %s",tmp,relpath);
209                         return NULL;
210                 }
211         strcpy(pattern,tmp);
212
213                 dirp = opendir( dirpath );
214                 if (dirp == NULL){
215                         fprintf(stdout, "[ERROR] Infile must be a .pgx file or a directory that contain pgx files");
216                         return NULL;
217                 }
218
219                 /*Read all .pgx files of directory */
220                 while ( (direntp = readdir( dirp )) != NULL )
221                 {
222                         /* Found a directory, but ignore . and .. */
223                         if(strcmp(".",direntp->d_name) == 0 || strcmp("..",direntp->d_name) == 0)
224                                         continue;
225                         
226                         if( ((pgx = strstr(direntp->d_name,pattern)) != NULL) && ((tmp2 = strstr(direntp->d_name,".pgx")) != NULL) ){
227                         
228                                 strcpy(tmp,dirpath);
229                                 tmp = strcat(tmp,direntp->d_name);
230                                                 
231                                 //Obtenemos el index de la secuencia de slices
232                                 if ((tmp2 = strpbrk (direntp->d_name, "0123456789")) == NULL) 
233                                         continue;
234                                 i = 0;
235                                 while (tmp2 != NULL) {                                  
236                                         tmpno[i++] = *tmp2;
237                                         point = tmp2;
238                                         tmp2 = strpbrk (tmp2+1,"0123456789");
239                                 }tmpno[i]='\0';
240
241                                 //Comprobamos que no estamos leyendo algo raro como pattern.jp3d
242                                 if ((point = strpbrk (point,".")) == NULL){
243                                         break;
244                                 }
245                                 //Slicepos --> index de slice; Sliceno --> no de slices hasta el momento
246                                 slicepos = atoi(tmpno);
247                                 pgxslicepos[sliceno] = slicepos - 1;
248                                 sliceno++;
249                                 if (slicepos>maxslice)
250                                         maxslice = slicepos;
251                                 
252                                 //Colocamos el slices en su posicion correspondiente
253                                 strcpy(pgxfiles[slicepos-1],tmp);
254                         }
255                 }
256         
257         }/* else if pattern*.pgx */
258
259         if (!sliceno) {
260                 fprintf(stdout,"[ERROR] No slices with this pattern founded !! Please check input volume name\n");
261                 return NULL;
262         }
263         /*if ( maxslice != sliceno) {
264                 fprintf(stdout,"[ERROR] Slices are not sequentially numbered !! Please rename them accordingly\n");
265                 return NULL;
266         }*/
267         
268         for (s=0;s<sliceno;s++)
269         {
270                         int pos = maxslice == sliceno ? s: pgxslicepos[s];
271                         f = fopen(pgxfiles[pos], "rb");
272                         if (!f) {
273                                 fprintf(stdout, "[ERROR] Failed to open %s for reading !\n", pgxfiles[s]);
274                                 return NULL;
275                         }
276                         fprintf(stdout, "[INFO] Loading %s \n",pgxfiles[pos]);
277
278                         fseek(f, 0, SEEK_SET);
279                         fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d",temp,&endian1,&endian2,signtmp,&prec,temp,&w,temp,&h);
280
281                         i=0;
282                         sign='+';               
283                         while (signtmp[i]!='\0') {
284                                 if (signtmp[i]=='-') sign='-';
285                                 i++;
286                         }
287                 
288                         fgetc(f);
289                         if (endian1=='M' && endian2=='L') {
290                                 cmptparm.bigendian = 1;
291                         } else if (endian2=='M' && endian1=='L') {
292                                 cmptparm.bigendian = 0;
293                         } else {
294                                 fprintf(stdout, "[ERROR] Bad pgx header, please check input file\n");
295                                 return NULL;
296                         }
297
298                         if (s==0){
299                                 /* initialize volume component */
300
301                                 cmptparm.x0 = parameters->volume_offset_x0;
302                                 cmptparm.y0 = parameters->volume_offset_y0;
303                                 cmptparm.z0 = parameters->volume_offset_z0;
304                                 cmptparm.w = !cmptparm.x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm.x0 + (w - 1) * parameters->subsampling_dx + 1;
305                                 cmptparm.h = !cmptparm.y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm.y0 + (h - 1) * parameters->subsampling_dy + 1;
306                                 cmptparm.l = !cmptparm.z0 ? (sliceno - 1) * parameters->subsampling_dz + 1 : cmptparm.z0 + (sliceno - 1) * parameters->subsampling_dz + 1;
307                                 
308                                 if (sign == '-') {
309                                         cmptparm.sgnd = 1;
310                                 } else {
311                                         cmptparm.sgnd = 0;
312                                 }
313                                 cmptparm.prec = prec;
314                                 cmptparm.bpp = prec;
315                                 cmptparm.dcoffset = parameters->dcoffset;
316                                 cmptparm.dx = parameters->subsampling_dx;
317                                 cmptparm.dy = parameters->subsampling_dy;
318                                 cmptparm.dz = parameters->subsampling_dz;
319                                 
320                                 /* create the volume */
321                                 volume = opj_volume_create(numcomps, &cmptparm, color_space);
322                                 if(!volume) {
323                                         fclose(f);
324                                         return NULL;
325                                 }
326                                 /* set volume offset and reference grid */
327                                 volume->x0 = cmptparm.x0;
328                                 volume->y0 = cmptparm.y0;
329                                 volume->z0 = cmptparm.z0;
330                                 volume->x1 = cmptparm.w;
331                                 volume->y1 = cmptparm.h;
332                                 volume->z1 = cmptparm.l;
333                                 
334                                 /* set volume data :only one component, that is a volume*/
335                                 comp = &volume->comps[0];
336                         
337                         }//if sliceno==1
338                         
339                         offset = w * h * s;
340                         
341                         for (i = 0; i < w * h; i++) {
342                                 int v;
343                                 if (comp->prec <= 8) {
344                                         if (!comp->sgnd) {
345                                                 v = readuchar(f);
346                                         } else {
347                                                 v = (char) readuchar(f);
348                                         }
349                                 } else if (comp->prec <= 16) {
350                                         if (!comp->sgnd) {
351                                                 v = readushort(f, cmptparm.bigendian);
352                                         } else {
353                                                 v = (short) readushort(f, cmptparm.bigendian);
354                                         }
355                                 } else {
356                                         if (!comp->sgnd) {
357                                                 v = readuint(f, cmptparm.bigendian);
358                                         } else {
359                                                 v = (int) readuint(f, cmptparm.bigendian);
360                                         }
361                                 }                               
362                                 if (v > maxvalue)
363                                         maxvalue = v;
364                                 comp->data[i + offset] = v;
365                                 
366                         }
367                         fclose(f);
368         } // for s --> sliceno
369         comp->bpp = int_floorlog2(maxvalue) + 1;
370         if (sliceno != 1)
371                 closedir( dirp );
372         //dump_volume(stdout, volume);
373         return volume;
374 }
375
376
377 int volumetopgx(opj_volume_t * volume, char *outfile) {
378         int w, wr, wrr, h, hr, hrr, l, lr, lrr;
379         int i, j, compno, offset, sliceno;
380         FILE *fdest = NULL;
381
382         for (compno = 0; compno < volume->numcomps; compno++) {
383                 opj_volume_comp_t *comp = &volume->comps[compno];
384                 char name[256];
385                 int nbytes = 0;
386                 char *tmp = outfile;
387                 while (*tmp) {
388                         tmp++;
389                 }
390                 while (*tmp!='.') {
391                         tmp--;
392                 }
393                 *tmp='\0';
394                 for(sliceno = 0; sliceno < volume->z1 - volume->z0; sliceno++) {
395
396                         if (volume->numcomps > 1) {
397                                 sprintf(name, "%s%d-%d.pgx", outfile, sliceno+1, compno);
398                         } else if ((volume->z1 - volume->z0) > 1) {
399                                 sprintf(name, "%s%d.pgx", outfile, sliceno+1);
400                         } else {
401                                 sprintf(name, "%s.pgx", outfile);
402                         }
403
404                         fdest = fopen(name, "wb");
405                         if (!fdest) {
406                                 fprintf(stdout, "[ERROR] Failed to open %s for writing \n", name);
407                                 return 1;
408                         }
409
410                         fprintf(stdout,"[INFO] Writing in %s (%s)\n",name,volume->comps[0].bigendian ? "Bigendian" : "Little-endian");
411
412                         w = int_ceildiv(volume->x1 - volume->x0, volume->comps[compno].dx);
413                         wr = volume->comps[compno].w;
414                         wrr = int_ceildivpow2(volume->comps[compno].w, volume->comps[compno].factor[0]);
415                         
416                         h = int_ceildiv(volume->y1 - volume->y0, volume->comps[compno].dy);
417                         hr = volume->comps[compno].h;
418                         hrr = int_ceildivpow2(volume->comps[compno].h, volume->comps[compno].factor[1]);
419                         
420                         l = int_ceildiv(volume->z1 - volume->z0, volume->comps[compno].dz);
421                         lr = volume->comps[compno].l;
422                         lrr = int_ceildivpow2(volume->comps[compno].l, volume->comps[compno].factor[2]);
423
424                         fprintf(fdest, "PG %c%c %c%d %d %d\n", comp->bigendian ? 'M':'L', comp->bigendian ? 'L':'M',comp->sgnd ? '-' : '+', comp->prec, wr, hr);
425                         if (comp->prec <= 8) {
426                                 nbytes = 1;
427                         } else if (comp->prec <= 16) {
428                                 nbytes = 2;
429                         } else {
430                                 nbytes = 4;
431                         }
432
433                         offset = (sliceno / lrr * l) + (sliceno % lrr);
434                         offset = wrr * hrr * offset;
435                         //fprintf(stdout,"%d %d %d %d\n",offset,wrr*hrr,wrr,w);
436                         for (i = 0; i < wrr * hrr; i++) {
437                                 int v = volume->comps[0].data[(i / wrr * w) + (i % wrr) + offset];
438                                 if (volume->comps[0].bigendian) {
439                                         for (j = nbytes - 1; j >= 0; j--) {
440                         char byte = (char) ((v >> (j * 8)) & 0xff);
441                         fwrite(&byte, 1, 1, fdest);
442                                         }
443                                 } else {
444                                         for (j = 0; j <= nbytes - 1; j++) {
445                         char byte = (char) ((v >> (j * 8)) & 0xff);
446                                                 fwrite(&byte, 1, 1, fdest);
447                                         }
448                                 }
449                         }
450
451                         fclose(fdest);
452                 }//for sliceno
453         }//for compno
454
455         return 0;
456 }
457
458 /* -->> -->> -->> -->>
459
460 BIN IMAGE FORMAT
461
462 <<-- <<-- <<-- <<-- */
463
464 opj_volume_t* bintovolume(char *filename, char *fileimg, opj_cparameters_t *parameters) {
465         int subsampling_dx =  parameters->subsampling_dx;
466         int subsampling_dy =  parameters->subsampling_dy;
467         int subsampling_dz =  parameters->subsampling_dz;
468         
469         int i, compno, w, h, l, numcomps = 1;
470         int prec, max = 0;
471
472 //      char temp[32];
473         char line[100];
474         int bigendian;
475         
476         FILE *f = NULL;
477         FILE *fimg = NULL;
478         OPJ_COLOR_SPACE color_space;
479         opj_volume_cmptparm_t cmptparm; /* maximum of 1 component */
480         opj_volume_t * volume = NULL;
481         opj_volume_comp_t *comp = NULL;
482
483         bigendian = 0;
484         color_space = CLRSPC_GRAY;
485
486         fimg = fopen(fileimg,"r");
487         if (!fimg) { 
488                 fprintf(stdout, "[ERROR] Failed to open %s for reading !!\n", fileimg);
489                 return 0;
490         }
491
492         fseek(fimg, 0, SEEK_SET);
493         while (!feof(fimg)) {
494         fgets(line,100,fimg);
495                 //fprintf(stdout,"%s %d \n",line,feof(fimg));
496                 if (strncmp(line,"Bpp",3) == 0){
497                         sscanf(line,"%*s%*[ \t]%d",&prec);
498                 } else if (strncmp(line,"Color",5) == 0){
499                         sscanf(line, "%*s%*[ \t]%d",&color_space);
500                 } else if (strncmp(line,"Dim",3) == 0){
501                         sscanf(line, "%*s%*[ \t]%d%*[ \t]%d%*[ \t]%d",&w,&h,&l);
502                 }
503         }
504         //fscanf(fimg, "Bpp%[ \t]%d%[ \t\n]",temp,&prec,temp);
505         //fscanf(fimg, "Color Map%[ \t]%d%[ \n\t]Dimensions%[ \t]%d%[ \t]%d%[ \t]%d%[ \n\t]",temp,&color_space,temp,temp,&w,temp,&h,temp,&l,temp);
506         //fscanf(fimg, "Resolution(mm)%[ \t]%d%[ \t]%d%[ \t]%d%[ \n\t]",temp,&subsampling_dx,temp,&subsampling_dy,temp,&subsampling_dz,temp);
507
508         #ifdef VERBOSE
509                 fprintf(stdout, "[INFO] %d \t %d %d %d \t %3.2f %2.2f %2.2f \t %d \n",color_space,w,h,l,subsampling_dx,subsampling_dy,subsampling_dz,prec);
510         #endif
511         fclose(fimg);
512         
513         /* initialize volume components */
514         memset(&cmptparm, 0, sizeof(opj_volume_cmptparm_t));
515         
516         cmptparm.prec = prec;
517         cmptparm.bpp = prec;
518         cmptparm.sgnd = 0;
519         cmptparm.bigendian = bigendian;
520         cmptparm.dcoffset = parameters->dcoffset;
521         cmptparm.dx = subsampling_dx;
522         cmptparm.dy = subsampling_dy;
523         cmptparm.dz = subsampling_dz;
524         cmptparm.w = w;
525         cmptparm.h = h;
526         cmptparm.l = l;
527         
528         /* create the volume */
529         volume = opj_volume_create(numcomps, &cmptparm, color_space);
530         if(!volume) {
531                 fprintf(stdout,"[ERROR] Unable to create volume");      
532                 fclose(f);
533                 return NULL;
534         }
535         
536         /* set volume offset and reference grid */
537         volume->x0 = parameters->volume_offset_x0;
538         volume->y0 = parameters->volume_offset_y0;
539         volume->z0 = parameters->volume_offset_z0;
540         volume->x1 = parameters->volume_offset_x0 + (w - 1) *   subsampling_dx + 1;
541         volume->y1 = parameters->volume_offset_y0 + (h - 1) *   subsampling_dy + 1;
542         volume->z1 = parameters->volume_offset_z0 + (l - 1) *   subsampling_dz + 1;
543         
544         /* set volume data */
545         f = fopen(filename, "rb");
546         if (!f) {
547                 fprintf(stdout, "[ERROR] Failed to open %s for reading !!\n", filename);
548                 return 0;
549         }
550         
551         /* BINARY */
552         for (compno = 0; compno < volume->numcomps; compno++) {
553                 int whl = w * h * l;
554                 /* set volume data */
555                 comp = &volume->comps[compno];
556                 
557                 /*if (comp->prec <= 8) {
558                         if (!comp->sgnd) {
559                 unsigned char *data = (unsigned char *) malloc(whl * sizeof(unsigned char));
560                                 fread(data, 1, whl, f);
561                                 for (i = 0; i < whl; i++) {
562                                         comp->data[i] = data[i];
563                                         if (comp->data[i] > max)
564                                                 max = comp->data[i];
565                                 }
566                                 free(data);
567                         } else {
568                                 char *data = (char *) malloc(whl);
569                                 fread(data, 1, whl, f);
570                                 for (i = 0; i < whl; i++) {
571                                         comp->data[i] = data[i];
572                                         if (comp->data[i] > max)
573                                                 max = comp->data[i];
574                                 }
575                                 free(data);
576                         }
577                 } else if (comp->prec <= 16) {
578                         if (!comp->sgnd) {
579                 unsigned short *data = (unsigned short *) malloc(whl * sizeof(unsigned short));
580                                 int leido = fread(data, 2, whl, f);
581                                 if (!leido)     {
582                                         free(data);     fclose(f);
583                                         return NULL;
584                                 }
585                                 
586                                 for (i = 0; i < whl; i++) {
587                                         if (bigendian)  //(c1 << 8) + c2;
588                                                 comp->data[i] = data[i];
589                                         else{                   //(c2 << 8) + c1;
590                                                 comp->data[i] = ShortSwap(data[i]);
591                                         }
592                                         if (comp->data[i] > max)
593                                                 max = comp->data[i];
594                                 }
595                                 free(data);
596                         } else {
597                                 short *data = (short *) malloc(whl);
598                                 int leido = fread(data, 2, whl, f);
599                                 if (!leido)     {
600                                         free(data);     fclose(f);
601                                         return NULL;
602                                 }
603                                 for (i = 0; i < whl; i++) {
604                                         if (bigendian){ //(c1 << 8) + c2;
605                                                 comp->data[i] = data[i];
606                                         }else{                  //(c2 << 8) + c1;
607                                                 comp->data[i] = (short) ShortSwap((unsigned short) data[i]);
608                                         }
609                                         if (comp->data[i] > max)
610                                                 max = comp->data[i];
611                                 }
612                                 free(data);
613                         }
614                 } else {
615                         if (!comp->sgnd) {
616                 unsigned int *data = (unsigned int *) malloc(whl * sizeof(unsigned int));
617                                 int leido = fread(data, 4, whl, f);
618                                 if (!leido)     {
619                                         free(data);     fclose(f);
620                                         return NULL;
621                                 }                               for (i = 0; i < whl; i++) {
622                                         if (!bigendian)
623                                                 comp->data[i] = LongSwap(data[i]);
624                                         else
625                                                 comp->data[i] = data[i];
626                                         if (comp->data[i] > max)
627                                                 max = comp->data[i];
628                                 }
629                                 free(data);
630                         } else {
631                                 int leido = fread(comp->data, 4, whl, f);
632                                 if (!leido)     {
633                                         fclose(f);
634                                         return NULL;
635                                 }                               
636                                 for (i = 0; i < whl; i++) {
637                                         if (!bigendian) 
638                                                 comp->data[i] = (int) LongSwap((unsigned int) comp->data[i]);
639                                         if (comp->data[i] > max)
640                                                 max = comp->data[i];
641                                 }
642                         }
643                 }*/
644                 
645                 for (i = 0; i < whl; i++) {
646                         int v;
647                         if (comp->prec <= 8) {
648                                 if (!comp->sgnd) {
649                                         v = readuchar(f);
650                                 } else {
651                                         v = (char) readuchar(f);
652                                 }
653                         } else if (comp->prec <= 16) {
654                                 if (!comp->sgnd) {
655                                         v = readushort(f, bigendian);
656                                 } else {
657                                         v = (short) readushort(f, bigendian);
658                                 }
659                         } else {
660                                 if (!comp->sgnd) {
661                                         v = readuint(f, bigendian);
662                                 } else {
663                                         v = (int) readuint(f, bigendian);
664                                 }
665                         }
666                         if (v > max)
667                                 max = v;
668                         comp->data[i] = v;
669                 }
670                 comp->bpp = int_floorlog2(max) + 1;
671         }
672         fclose(f);
673         return volume;
674 }
675
676 int volumetobin(opj_volume_t * volume, char *outfile) {
677         int w, wr, wrr, h, hr, hrr, l, lr, lrr, max;
678         int i,j, compno, nbytes;
679         int offset, sliceno;
680         FILE *fdest = NULL;
681         FILE *fimgdest = NULL;
682 //      char *imgtemp;
683         char name[256];
684
685         for (compno = 0; compno < 1; compno++) { //Only one component
686                 
687                 fdest = fopen(outfile, "wb");
688                 if (!fdest) {
689                         fprintf(stdout, "[ERROR] Failed to open %s for writing\n", outfile);
690                         return 1;
691                 }
692         fprintf(stdout,"[INFO] Writing outfile %s (%s) \n",outfile, volume->comps[0].bigendian ? "Bigendian" : "Little-endian");
693
694                 w = int_ceildiv(volume->x1 - volume->x0, volume->comps[compno].dx);
695                 wr = volume->comps[compno].w;
696                 wrr = int_ceildivpow2(volume->comps[compno].w, volume->comps[compno].factor[0]);
697                 
698                 h = int_ceildiv(volume->y1 - volume->y0, volume->comps[compno].dy);
699                 hr = volume->comps[compno].h;
700                 hrr = int_ceildivpow2(volume->comps[compno].h, volume->comps[compno].factor[1]);
701                 
702                 l = int_ceildiv(volume->z1 - volume->z0, volume->comps[compno].dz);
703                 lr = volume->comps[compno].l;
704                 lrr = int_ceildivpow2(volume->comps[compno].l, volume->comps[compno].factor[2]);
705
706                 max = (volume->comps[compno].prec <= 8) ? 255 : (1 << volume->comps[compno].prec) - 1;
707                 
708                 volume->comps[compno].x0 = int_ceildivpow2(volume->comps[compno].x0 - int_ceildiv(volume->x0, volume->comps[compno].dx), volume->comps[compno].factor[0]);
709                 volume->comps[compno].y0 = int_ceildivpow2(volume->comps[compno].y0 - int_ceildiv(volume->y0, volume->comps[compno].dy), volume->comps[compno].factor[1]);
710                 volume->comps[compno].z0 = int_ceildivpow2(volume->comps[compno].z0 - int_ceildiv(volume->z0, volume->comps[compno].dz), volume->comps[compno].factor[2]);
711                 
712                 if (volume->comps[0].prec <= 8) {
713                         nbytes = 1;
714                 } else if (volume->comps[0].prec <= 16) {
715                         nbytes = 2;
716                 } else {
717                         nbytes = 4;
718                 }
719
720                 //fprintf(stdout,"w %d wr %d wrr %d h %d hr %d hrr %d l %d lr %d lrr %d max %d nbytes %d\n Factor %d %d %d",w,wr,wrr,h,hr,hrr,l,lr,lrr,max,nbytes,volume->comps[compno].factor[0],volume->comps[compno].factor[1],volume->comps[compno].factor[2]);
721
722                 for(sliceno = 0; sliceno < lrr; sliceno++) {
723                         offset = (sliceno / lrr * l) + (sliceno % lrr);
724             offset = wrr * hrr * offset;
725                         for (i = 0; i < wrr * hrr; i++) {
726                                 int v = volume->comps[0].data[(i / wrr * w) + (i % wrr) + offset];
727                                 if (volume->comps[0].bigendian) {
728                                         for (j = nbytes - 1; j >= 0; j--) {
729                         char byte = (char) ((v >> (j * 8)) & 0xff);
730                         fwrite(&byte, 1, 1, fdest);
731                                         }
732                                 } else {
733                                         for (j = 0; j <= nbytes - 1; j++) {
734                         char byte = (char) ((v >> (j * 8)) & 0xff);
735                                                 fwrite(&byte, 1, 1, fdest);
736                                         }
737                                 }
738                         }
739                 }
740         
741         }
742         
743         fclose(fdest);
744
745         sprintf(name,"%s.img",outfile);
746         fimgdest = fopen(name, "w");
747                 if (!fimgdest) {
748                         fprintf(stdout, "[ERROR] Failed to open %s for writing\n", name);
749                         return 1;
750                 }
751         fprintf(fimgdest, "Bpp\t%d\nColor Map\t2\nDimensions\t%d\t%d\t%d\nResolution(mm)\t%d\t%d\t%d\t\n",
752                 volume->comps[0].prec,wrr,hrr,lrr,volume->comps[0].dx,volume->comps[0].dy,volume->comps[0].dz);
753
754         fclose(fimgdest);
755         return 0;
756 }
757 /* -->> -->> -->> -->>
758
759 IMG IMAGE FORMAT
760
761 <<-- <<-- <<-- <<-- */
762 opj_volume_t* imgtovolume(char *fileimg, opj_cparameters_t *parameters) {
763         int subsampling_dx =  parameters->subsampling_dx;
764         int subsampling_dy =  parameters->subsampling_dy;
765         int subsampling_dz =  parameters->subsampling_dz;
766         
767         int i, compno, w, h, l, numcomps = 1;
768         int prec, max = 0, min = 0;
769         float dx, dy, dz;
770         char filename[100], tmpdirpath[100], dirpath[100], *tmp;
771         char line[100], datatype[100];
772         int bigendian;
773         
774         FILE *f = NULL;
775         FILE *fimg = NULL;
776         OPJ_COLOR_SPACE color_space;
777         opj_volume_cmptparm_t cmptparm; /* maximum of 1 component */
778         opj_volume_t * volume = NULL;
779         opj_volume_comp_t *comp = NULL;
780
781         bigendian = 0;
782         color_space = CLRSPC_GRAY;
783
784         fimg = fopen(fileimg,"r");
785         if (!fimg) { 
786                 fprintf(stderr, "[ERROR] Failed to open %s for reading !!\n", fileimg);
787                 return 0;
788         }
789
790         //Fetch only the path 
791         strcpy(tmpdirpath,fileimg);
792         if ((tmp = strrchr(tmpdirpath,'/')) != NULL){
793                 tmp++; *tmp='\0';
794                 strcpy(dirpath,tmpdirpath);
795         } else {
796                 strcpy(dirpath,"./");
797         }
798
799         fseek(fimg, 0, SEEK_SET);
800         while (!feof(fimg)) {
801         fgets(line,100,fimg);
802                 //fprintf(stdout,"%s %d \n",line,feof(fimg));
803                 if (strncmp(line,"Image",5) == 0){
804                         sscanf(line,"%*s%*[ \t]%s",datatype);
805                 } else if (strncmp(line,"File",4) == 0){
806                         sscanf(line,"%*s %*s%*[ \t]%s",filename);
807                         strcat(dirpath, filename);
808                         strcpy(filename,dirpath);
809                 } else if (strncmp(line,"Min",3) == 0){
810                         sscanf(line,"%*s %*s%*[ \t]%d%*[ \t]%d",&min,&max);
811                         prec = int_floorlog2(max - min + 1);
812                 } else if (strncmp(line,"Bpp",3) == 0){
813                         sscanf(line,"%*s%*[ \t]%d",&prec);
814                 } else if (strncmp(line,"Color",5) == 0){
815                         sscanf(line, "%*s %*s%*[ \t]%d",&color_space);
816                 } else if (strncmp(line,"Dim",3) == 0){
817                         sscanf(line, "%*s%*[ \t]%d%*[ \t]%d%*[ \t]%d",&w,&h,&l);
818                 } else if (strncmp(line,"Res",3) == 0){
819                         sscanf(line,"%*s%*[ \t]%f%*[ \t]%f%*[ \t]%f",&dx,&dy,&dz);
820                 }
821
822         }
823         #ifdef VERBOSE
824                 fprintf(stdout, "[INFO] %s %d \t %d %d %d \t %f %f %f \t %d %d %d \n",filename,color_space,w,h,l,dx,dy,dz,max,min,prec);
825         #endif
826         fclose(fimg);
827
828         /* error control */
829         if ( !prec || !w || !h || !l ){
830                 fprintf(stderr,"[ERROR] Unable to read IMG file correctly. Found some null values.");   
831                 return NULL;
832         }
833
834         /* initialize volume components */
835         memset(&cmptparm, 0, sizeof(opj_volume_cmptparm_t));
836         
837         cmptparm.prec = prec;
838         cmptparm.bpp = prec;
839         cmptparm.sgnd = 0;
840         cmptparm.bigendian = bigendian;
841         cmptparm.dcoffset = parameters->dcoffset;
842         cmptparm.dx = subsampling_dx;
843         cmptparm.dy = subsampling_dy;
844         cmptparm.dz = subsampling_dz;
845         cmptparm.w = w;
846         cmptparm.h = h;
847         cmptparm.l = l;
848         
849         /* create the volume */
850         volume = opj_volume_create(numcomps, &cmptparm, color_space);
851         if(!volume) {
852                 fprintf(stdout,"[ERROR] Unable to create volume");      
853                 return NULL;
854         }
855         
856         /* set volume offset and reference grid */
857         volume->x0 = parameters->volume_offset_x0;
858         volume->y0 = parameters->volume_offset_y0;
859         volume->z0 = parameters->volume_offset_z0;
860         volume->x1 = parameters->volume_offset_x0 + (w - 1) *   subsampling_dx + 1;
861         volume->y1 = parameters->volume_offset_y0 + (h - 1) *   subsampling_dy + 1;
862         volume->z1 = parameters->volume_offset_z0 + (l - 1) *   subsampling_dz + 1;
863         
864         max = 0;
865         /* set volume data */
866         f = fopen(filename, "rb");
867         if (!f) {
868                 fprintf(stderr, "[ERROR] Failed to open %s for reading !!\n", filename);
869                 fclose(f);
870                 return 0;
871         }
872         
873         /* BINARY */
874         for (compno = 0; compno < volume->numcomps; compno++) {
875                 int whl = w * h * l;
876                 /* set volume data */
877                 comp = &volume->comps[compno];
878                 
879                 /*if (comp->prec <= 8) {
880                         if (!comp->sgnd) {
881                 unsigned char *data = (unsigned char *) malloc(whl * sizeof(unsigned char));
882                                 fread(data, 1, whl, f);
883                                 for (i = 0; i < whl; i++) {
884                                         comp->data[i] = data[i];
885                                         if (comp->data[i] > max)
886                                                 max = comp->data[i];
887                                 }
888                                 free(data);
889                         } else {
890                                 char *data = (char *) malloc(whl);
891                                 fread(data, 1, whl, f);
892                                 for (i = 0; i < whl; i++) {
893                                         comp->data[i] = data[i];
894                                         if (comp->data[i] > max)
895                                                 max = comp->data[i];
896                                 }
897                                 free(data);
898                         }
899                 } else if (comp->prec <= 16) {
900                         if (!comp->sgnd) {
901                 unsigned short *data = (unsigned short *) malloc(whl * sizeof(unsigned short));
902                                 int leido = fread(data, 2, whl, f);
903                                 if (!leido)     {
904                                         free(data);     fclose(f);
905                                         return NULL;
906                                 }
907                                 
908                                 for (i = 0; i < whl; i++) {
909                                         if (bigendian)  //(c1 << 8) + c2;
910                                                 comp->data[i] = data[i];
911                                         else{                   //(c2 << 8) + c1;
912                                                 comp->data[i] = ShortSwap(data[i]);
913                                         }
914                                         if (comp->data[i] > max)
915                                                 max = comp->data[i];
916                                 }
917                                 free(data);
918                         } else {
919                                 short *data = (short *) malloc(whl);
920                                 int leido = fread(data, 2, whl, f);
921                                 if (!leido)     {
922                                         free(data);     fclose(f);
923                                         return NULL;
924                                 }
925                                 for (i = 0; i < whl; i++) {
926                                         if (bigendian){ //(c1 << 8) + c2;
927                                                 comp->data[i] = data[i];
928                                         }else{                  //(c2 << 8) + c1;
929                                                 comp->data[i] = (short) ShortSwap((unsigned short) data[i]);
930                                         }
931                                         if (comp->data[i] > max)
932                                                 max = comp->data[i];
933                                 }
934                                 free(data);
935                         }
936                 } else {
937                         if (!comp->sgnd) {
938                 unsigned int *data = (unsigned int *) malloc(whl * sizeof(unsigned int));
939                                 int leido = fread(data, 4, whl, f);
940                                 if (!leido)     {
941                                         free(data);     fclose(f);
942                                         return NULL;
943                                 }                               for (i = 0; i < whl; i++) {
944                                         if (!bigendian)
945                                                 comp->data[i] = LongSwap(data[i]);
946                                         else
947                                                 comp->data[i] = data[i];
948                                         if (comp->data[i] > max)
949                                                 max = comp->data[i];
950                                 }
951                                 free(data);
952                         } else {
953                                 int leido = fread(comp->data, 4, whl, f);
954                                 if (!leido)     {
955                                         fclose(f);
956                                         return NULL;
957                                 }                               
958                                 for (i = 0; i < whl; i++) {
959                                         if (!bigendian) 
960                                                 comp->data[i] = (int) LongSwap((unsigned int) comp->data[i]);
961                                         if (comp->data[i] > max)
962                                                 max = comp->data[i];
963                                 }
964                         }
965                 }*/
966                 
967                 for (i = 0; i < whl; i++) {
968                         int v;
969                         if (comp->prec <= 8) {
970                                 if (!comp->sgnd) {
971                                         v = readuchar(f);
972                                 } else {
973                                         v = (char) readuchar(f);
974                                 }
975                         } else if (comp->prec <= 16) {
976                                 if (!comp->sgnd) {
977                                         v = readushort(f, bigendian);
978                                 } else {
979                                         v = (short) readushort(f, bigendian);
980                                 }
981                         } else {
982                                 if (!comp->sgnd) {
983                                         v = readuint(f, bigendian);
984                                 } else {
985                                         v = (int) readuint(f, bigendian);
986                                 }
987                         }
988                         if (v > max)
989                                 max = v;
990                         comp->data[i] = v;
991                 }
992                 comp->bpp = int_floorlog2(max) + 1;
993         }
994         fclose(f);
995         return volume;
996 }
997