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