jp3d/jpwl/mj2/jpip: Fix resource leaks (#1226)
[openjpeg.git] / src / lib / openmj2 / mj2_convert.c
1 /*
2 * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
3 * Copyright (c) 2002-2014, Professor Benoit Macq
4 * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "opj_includes.h"
30 #include "mj2_convert.h"
31
32 /*  -----------------------       */
33 /*                    */
34 /*                    */
35 /*  Count the number of frames        */
36 /*  in a YUV file             */
37 /*                    */
38 /*  -----------------------       */
39
40 unsigned int OPJ_CALLCONV yuv_num_frames(mj2_tk_t * tk, char *infile)
41 {
42     unsigned int prec_size;
43     long end_of_f, frame_size;
44     FILE *f;
45
46     f = fopen(infile, "rb");
47     if (!f) {
48         fprintf(stderr, "failed to open %s for reading\n", infile);
49         return 0;
50     }
51     prec_size = (tk->depth + 7) / 8; /* bytes of precision */
52
53     frame_size = (long)(tk->w * tk->h * (1.0 + (double) 2 / (double)(
54             tk->CbCr_subsampling_dx *
55             tk->CbCr_subsampling_dy)));  /* Calculate frame size */
56     frame_size *= prec_size;
57
58     fseek(f, 0, SEEK_END);
59     end_of_f = ftell(f);      /* Calculate file size */
60
61     if (end_of_f < frame_size) {
62         fprintf(stderr,
63                 "YUV does not contains any frame of %d x %d size\n", tk->w,
64                 tk->h);
65         fclose(f);
66         return 0;
67     }
68     fclose(f);
69
70     return (unsigned int)(end_of_f / frame_size);
71 }
72
73 /*  ----------------------- */
74 /* */
75 /* */
76 /*  YUV to IMAGE */
77 /* */
78 /*  ----------------------- */
79
80 opj_image_t * OPJ_CALLCONV mj2_image_create(mj2_tk_t * tk,
81         opj_cparameters_t *parameters)
82 {
83     opj_image_cmptparm_t cmptparm[3];
84     opj_image_t * img;
85     int i;
86     int numcomps = 3;
87     int subsampling_dx = parameters->subsampling_dx;
88     int subsampling_dy = parameters->subsampling_dy;
89
90     /* initialize image components */
91     memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
92     for (i = 0; i < numcomps; i++) {
93         cmptparm[i].prec = tk->depth;
94         cmptparm[i].bpp = tk->depth;
95         cmptparm[i].sgnd = 0;
96         cmptparm[i].dx = i ? subsampling_dx * tk->CbCr_subsampling_dx : subsampling_dx;
97         cmptparm[i].dy = i ? subsampling_dy * tk->CbCr_subsampling_dy : subsampling_dy;
98         cmptparm[i].w = tk->w;
99         cmptparm[i].h = tk->h;
100     }
101     /* create the image */
102     img = opj_image_create(numcomps, cmptparm, CLRSPC_SRGB);
103     return img;
104 }
105
106 char OPJ_CALLCONV yuvtoimage(mj2_tk_t * tk, opj_image_t * img, int frame_num,
107                              opj_cparameters_t *parameters, char* infile)
108 {
109     int i, compno;
110     int offset, size, max, prec_bytes, is_16, v;
111     long end_of_f, position;
112     int numcomps = 3;
113     int subsampling_dx = parameters->subsampling_dx;
114     int subsampling_dy = parameters->subsampling_dy;
115     FILE *yuvfile;
116     int *data;
117     unsigned char uc;
118
119     yuvfile = fopen(infile, "rb");
120     if (!yuvfile) {
121         fprintf(stderr, "failed to open %s for readings\n", parameters->infile);
122         return 1;
123     }
124     is_16 = (tk->depth > 8);
125     prec_bytes = (is_16 ? 2 : 1);
126
127     offset = (int)((double)(frame_num * tk->w * tk->h) * (1.0 +
128                    1.0 * (double) 2 / (double)(tk->CbCr_subsampling_dx *
129                            tk->CbCr_subsampling_dy)));
130     offset *= prec_bytes;
131
132     fseek(yuvfile, 0, SEEK_END);
133     end_of_f = ftell(yuvfile);
134     fseek(yuvfile, sizeof(unsigned char) * offset, SEEK_SET);
135     position = ftell(yuvfile);
136     if (position >= end_of_f) {
137         fprintf(stderr, "Cannot reach frame number %d in yuv file !!\n",
138                 frame_num);
139         fclose(yuvfile);
140         return 1;
141     }
142
143     img->x0 = tk->Dim[0];
144     img->y0 = tk->Dim[1];
145     img->x1 = !tk->Dim[0] ? (tk->w - 1) * subsampling_dx + 1 : tk->Dim[0] +
146               (tk->w - 1) * subsampling_dx + 1;
147     img->y1 = !tk->Dim[1] ? (tk->h - 1) * subsampling_dy + 1 : tk->Dim[1] +
148               (tk->h - 1) * subsampling_dy + 1;
149
150     size = tk->w * tk->h * prec_bytes;
151
152     for (compno = 0; compno < numcomps; compno++) {
153         max = size / (img->comps[compno].dx * img->comps[compno].dy);
154         data = img->comps[compno].data;
155
156         for (i = 0; i < max && !feof(yuvfile); i++) {
157             v = 0;
158             fread(&uc, 1, 1, yuvfile);
159             v = uc;
160
161             if (is_16) {
162                 fread(&uc, 1, 1, yuvfile);
163                 v |= (uc << 8);
164             }
165             *data++ = v;
166         }
167     }
168     fclose(yuvfile);
169
170     return 0;
171 }
172
173
174
175 /*  ----------------------- */
176 /* */
177 /* */
178 /*  IMAGE to YUV */
179 /* */
180 /*  ----------------------- */
181
182
183 opj_bool OPJ_CALLCONV imagetoyuv(opj_image_t * img, char *outfile)
184 {
185     FILE *f;
186     int *data;
187     int i, v, is_16, prec_bytes;
188     unsigned char buf[2];
189
190     if (img->numcomps == 3) {
191         if (img->comps[0].dx != img->comps[1].dx / 2
192                 || img->comps[1].dx != img->comps[2].dx) {
193             fprintf(stderr,
194                     "Error with the input image components size: cannot create yuv file)\n");
195             return OPJ_FALSE;
196         }
197     } else if (!(img->numcomps == 1)) {
198         fprintf(stderr,
199                 "Error with the number of image components(must be one or three)\n");
200         return OPJ_FALSE;
201     }
202
203     f = fopen(outfile, "a+b");
204     if (!f) {
205         fprintf(stderr, "failed to open %s for writing\n", outfile);
206         return OPJ_FALSE;
207     }
208     is_16 = (img->comps[0].prec > 8);
209     prec_bytes = (is_16 ? 2 : 1);
210     data = img->comps[0].data;
211
212     for (i = 0; i < (img->comps[0].w * img->comps[0].h); i++) {
213         v = *data++;
214         buf[0] = (unsigned char)v;
215
216         if (is_16) {
217             buf[1] = (unsigned char)(v >> 8);
218         }
219
220         fwrite(buf, 1, prec_bytes, f);
221     }
222
223
224     if (img->numcomps == 3) {
225         data = img->comps[1].data;
226
227         for (i = 0; i < (img->comps[1].w * img->comps[1].h); i++) {
228             v = *data++;
229             buf[0] = (unsigned char)v;
230
231             if (is_16) {
232                 buf[1] = (unsigned char)(v >> 8);
233             }
234
235             fwrite(buf, 1, prec_bytes, f);
236         }
237         data = img->comps[2].data;
238
239         for (i = 0; i < (img->comps[2].w * img->comps[2].h); i++) {
240             v = *data++;
241             buf[0] = (unsigned char)v;
242
243             if (is_16) {
244                 buf[1] = (unsigned char)(v >> 8);
245             }
246
247             fwrite(buf, 1, prec_bytes, f);
248         }
249     } else if (img->numcomps == 1) {
250         /* fake CbCr values */
251         if (is_16) {
252             buf[0] = 255;
253             if (img->comps[0].prec == 10) {
254                 buf[1] = 1;
255             } else if (img->comps[0].prec == 12) {
256                 buf[1] = 3;
257             } else {
258                 buf[1] = 125;
259             }
260         } else {
261             buf[0] = 125;
262         }
263
264         for (i = 0; i < (img->comps[0].w * img->comps[0].h * 0.25); i++) {
265             fwrite(buf, 1, prec_bytes, f);
266         }
267
268
269         for (i = 0; i < (img->comps[0].w * img->comps[0].h * 0.25); i++) {
270             fwrite(buf, 1, prec_bytes, f);
271         }
272     }
273     fclose(f);
274     return OPJ_TRUE;
275 }
276
277 /*  ----------------------- */
278 /* */
279 /* */
280 /*  IMAGE to BMP */
281 /* */
282 /*  ----------------------- */
283
284 int OPJ_CALLCONV imagetobmp(opj_image_t * img, char *outfile)
285 {
286     int w, wr, h, hr, i, pad;
287     FILE *f;
288
289     if (img->numcomps == 3 && img->comps[0].dx == img->comps[1].dx
290             && img->comps[1].dx == img->comps[2].dx
291             && img->comps[0].dy == img->comps[1].dy
292             && img->comps[1].dy == img->comps[2].dy
293             && img->comps[0].prec == img->comps[1].prec
294             && img->comps[1].prec == img->comps[2].prec) {
295         /* -->> -->> -->> -->>
296
297           24 bits color
298
299         <<-- <<-- <<-- <<-- */
300
301         f = fopen(outfile, "wb");
302         if (!f) {
303             fprintf(stderr, "failed to open %s for writing\n", outfile);
304             return 1;
305         }
306
307         w = img->comps[0].w;
308         wr = int_ceildivpow2(img->comps[0].w, img->comps[0].factor);
309
310         h = img->comps[0].h;
311         hr = int_ceildivpow2(img->comps[0].h, img->comps[0].factor);
312
313         fprintf(f, "BM");
314
315         /* FILE HEADER */
316         /* ------------- */
317         fprintf(f, "%c%c%c%c",
318                 (unsigned char)(hr * wr * 3 + 3 * hr * (wr % 2) +
319                                 54) & 0xff,
320                 (unsigned char)((hr * wr * 3 + 3 * hr * (wr % 2) + 54)
321                                 >> 8) & 0xff,
322                 (unsigned char)((hr * wr * 3 + 3 * hr * (wr % 2) + 54)
323                                 >> 16) & 0xff,
324                 (unsigned char)((hr * wr * 3 + 3 * hr * (wr % 2) + 54)
325                                 >> 24) & 0xff);
326         fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff,
327                 ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
328         fprintf(f, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,
329                 ((54) >> 16) & 0xff, ((54) >> 24) & 0xff);
330
331         /* INFO HEADER   */
332         /* ------------- */
333         fprintf(f, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,
334                 ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
335         fprintf(f, "%c%c%c%c", (unsigned char)((wr) & 0xff),
336                 (unsigned char)((wr) >> 8) & 0xff,
337                 (unsigned char)((wr) >> 16) & 0xff,
338                 (unsigned char)((wr) >> 24) & 0xff);
339         fprintf(f, "%c%c%c%c", (unsigned char)((hr) & 0xff),
340                 (unsigned char)((hr) >> 8) & 0xff,
341                 (unsigned char)((hr) >> 16) & 0xff,
342                 (unsigned char)((hr) >> 24) & 0xff);
343         fprintf(f, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
344         fprintf(f, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff);
345         fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff,
346                 ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
347         fprintf(f, "%c%c%c%c",
348                 (unsigned char)(3 * hr * wr +
349                                 3 * hr * (wr % 2)) & 0xff,
350                 (unsigned char)((hr * wr * 3 + 3 * hr * (wr % 2)) >>
351                                 8) & 0xff,
352                 (unsigned char)((hr * wr * 3 + 3 * hr * (wr % 2)) >>
353                                 16) & 0xff,
354                 (unsigned char)((hr * wr * 3 + 3 * hr * (wr % 2)) >>
355                                 24) & 0xff);
356         fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff,
357                 ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
358         fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff,
359                 ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
360         fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff,
361                 ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
362         fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff,
363                 ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
364
365         for (i = 0; i < wr * hr; i++) {
366             unsigned char R, G, B;
367             /* a modifier */
368             /* R = img->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];*/
369             R = img->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
370             /* G = img->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];*/
371             G = img->comps[1].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
372             /* B = img->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];*/
373             B = img->comps[2].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
374             fprintf(f, "%c%c%c", B, G, R);
375
376             if ((i + 1) % wr == 0) {
377                 for (pad = (3 * wr) % 4 ? 4 - (3 * wr) % 4 : 0; pad > 0; pad--) { /* ADD */
378                     fprintf(f, "%c", 0);
379                 }
380             }
381         }
382         fclose(f);
383     }
384     return 0;
385 }