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