manage case 0 frames inside yuv_num_frames function and correct some warnings with...
[openjpeg.git] / applications / mj2 / mj2_convert.c
1 /*
2 * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
3 * Copyright (c) 2002-2007, 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.h"
31
32 /*  -----------------------           */
33 /*                                    */
34 /*                                    */
35 /*  Count the number of frames        */
36 /*  in a YUV file                     */
37 /*                                    */
38 /*  -----------------------           */
39
40 unsigned int 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) (tk->CbCr_subsampling_dx * tk->CbCr_subsampling_dy)));      /* Calculate frame size */
54         frame_size *= prec_size; 
55         
56   fseek(f, 0, SEEK_END);
57   end_of_f = ftell(f);          /* Calculate file size */
58         
59   if (end_of_f < frame_size) {
60     fprintf(stderr,
61                         "YUV does not contains any frame of %d x %d size\n", tk->w,
62                         tk->h);
63     return 0;
64   }
65   fclose(f);
66         
67   return (unsigned int)(end_of_f / frame_size);
68 }
69
70 //  -----------------------
71 //
72 //
73 //  YUV to IMAGE
74 //
75 //  -----------------------
76
77 opj_image_t *mj2_image_create(mj2_tk_t * tk, opj_cparameters_t *parameters)
78 {
79         opj_image_cmptparm_t cmptparm[3];
80         opj_image_t * img;
81         int i;
82         int numcomps = 3;
83         int subsampling_dx = parameters->subsampling_dx;
84         int subsampling_dy = parameters->subsampling_dy;
85
86         /* initialize image components */
87         memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
88         for(i = 0; i < numcomps; i++) {
89                 cmptparm[i].prec = tk->depth;
90                 cmptparm[i].bpp = tk->depth;
91                 cmptparm[i].sgnd = 0;           
92                 cmptparm[i].dx = i ? subsampling_dx * tk->CbCr_subsampling_dx : subsampling_dx;
93                 cmptparm[i].dy = i ? subsampling_dy * tk->CbCr_subsampling_dy : subsampling_dy;
94                 cmptparm[i].w = tk->w;
95                 cmptparm[i].h = tk->h;
96         }
97         /* create the image */
98         img = opj_image_create(numcomps, cmptparm, CLRSPC_SRGB);
99         return img;
100 }
101
102 char yuvtoimage(mj2_tk_t * tk, opj_image_t * img, int frame_num, opj_cparameters_t *parameters, char* infile)
103 {
104   int i, compno;
105   int offset, size, max, prec_bytes, is_16, v;
106   long end_of_f, position;
107         int numcomps = 3;
108         int subsampling_dx = parameters->subsampling_dx;
109         int subsampling_dy = parameters->subsampling_dy;
110         FILE *yuvfile;
111         int *data;
112         unsigned char uc;
113
114   yuvfile = fopen(infile,"rb");
115   if (!yuvfile) {  
116     fprintf(stderr, "failed to open %s for readings\n",parameters->infile);
117     return 1;
118   }
119         is_16 = (tk->depth > 8);
120         prec_bytes = (is_16?2:1);
121
122   offset = (int) ((double) (frame_num * tk->w * tk->h) * (1.0 +
123                 1.0 * (double) 2 / (double) (tk->CbCr_subsampling_dx * tk->CbCr_subsampling_dy)));
124   offset *= prec_bytes;
125
126   fseek(yuvfile, 0, SEEK_END);
127   end_of_f = ftell(yuvfile);
128   fseek(yuvfile, sizeof(unsigned char) * offset, SEEK_SET);
129   position = ftell(yuvfile);
130   if (position >= end_of_f) {
131     fprintf(stderr, "Cannot reach frame number %d in yuv file !!\n",
132                         frame_num);
133                 fclose(yuvfile);
134     return 1;
135   }
136         
137   img->x0 = tk->Dim[0];
138   img->y0 = tk->Dim[1];
139   img->x1 = !tk->Dim[0] ? (tk->w - 1) * subsampling_dx + 1 : tk->Dim[0] +
140     (tk->w - 1) * subsampling_dx + 1;
141   img->y1 = !tk->Dim[1] ? (tk->h - 1) * subsampling_dy + 1 : tk->Dim[1] +
142     (tk->h - 1) * subsampling_dy + 1;
143
144         size = tk->w * tk->h * prec_bytes;
145         
146         for(compno = 0; compno < numcomps; compno++) 
147    {
148         max = size/(img->comps[compno].dx * img->comps[compno].dy);
149         data = img->comps[compno].data;
150
151         for (i = 0; i < max && !feof(yuvfile); i++)
152   {
153         v = 0;
154         fread(&uc, 1, 1, yuvfile);
155         v = uc;
156
157         if(is_16)
158  {
159         fread(&uc, 1, 1, yuvfile);
160         v |= (uc<<8);
161  }
162         *data++ = v;
163   }
164    }
165         fclose(yuvfile);
166         
167   return 0;
168 }
169
170
171
172 //  -----------------------
173 //
174 //
175 //  IMAGE to YUV
176 //
177 //  -----------------------
178
179
180 opj_bool imagetoyuv(opj_image_t * img, char *outfile)
181 {
182   FILE *f;
183   int *data;
184   int i, v, is_16, prec_bytes;
185   unsigned char buf[2];
186
187   if (img->numcomps == 3) {
188     if (img->comps[0].dx != img->comps[1].dx / 2
189       || img->comps[1].dx != img->comps[2].dx) {
190       fprintf(stderr,
191                                 "Error with the input image components size: cannot create yuv file)\n");
192       return OPJ_FALSE;
193     }
194   } else if (!(img->numcomps == 1)) {
195     fprintf(stderr,
196       "Error with the number of image components(must be one or three)\n");
197     return OPJ_FALSE;
198   }
199   
200   f = fopen(outfile, "a+b");
201   if (!f) {
202     fprintf(stderr, "failed to open %s for writing\n", outfile);
203     return OPJ_FALSE;
204   }
205   is_16 = (img->comps[0].prec > 8);
206   prec_bytes = (is_16?2:1);
207   data = img->comps[0].data;
208   
209   for (i = 0; i < (img->comps[0].w * img->comps[0].h); i++) {
210     v = *data++;
211     buf[0] = (unsigned char)v;
212
213         if(is_16) buf[1] = (unsigned char)(v>>8);
214
215     fwrite(buf, 1, prec_bytes, f);
216   }
217   
218   
219   if (img->numcomps == 3) {
220         data = img->comps[1].data;
221
222     for (i = 0; i < (img->comps[1].w * img->comps[1].h); i++) {
223       v = *data++;
224       buf[0] = (unsigned char)v;
225
226       if(is_16) buf[1] = (unsigned char)(v>>8);
227
228       fwrite(buf, 1, prec_bytes, f);
229     }
230     data = img->comps[2].data;
231     
232     for (i = 0; i < (img->comps[2].w * img->comps[2].h); i++) {
233       v = *data++;
234       buf[0] = (unsigned char)v;
235
236       if(is_16) buf[1] = (unsigned char)(v>>8);
237
238       fwrite(buf, 1, prec_bytes, f);
239     }
240   } else if (img->numcomps == 1) {
241 /* fake CbCr values */
242         if(is_16) 
243   { 
244         buf[0] = 255;
245         if(img->comps[0].prec == 10) buf[1] = 1;
246         else
247         if(img->comps[0].prec == 12) buf[1] = 3;
248         else
249          buf[1] = 125;
250   } 
251         else buf[0] = 125;
252
253     for (i = 0; i < (img->comps[0].w * img->comps[0].h * 0.25); i++) {
254       fwrite(buf, 1, prec_bytes, f);
255     }
256     
257     
258     for (i = 0; i < (img->comps[0].w * img->comps[0].h * 0.25); i++) {
259       fwrite(buf, 1, prec_bytes, f);
260     }
261   }  
262   fclose(f);
263   return OPJ_TRUE;
264 }
265
266 //  -----------------------
267 //
268 //
269 //  IMAGE to BMP
270 //
271 //  -----------------------
272
273 int imagetobmp(opj_image_t * img, char *outfile) {
274   int w,wr,h,hr,i,pad;
275   FILE *f;
276   
277   if (img->numcomps == 3 && img->comps[0].dx == img->comps[1].dx
278     && img->comps[1].dx == img->comps[2].dx
279     && img->comps[0].dy == img->comps[1].dy
280     && img->comps[1].dy == img->comps[2].dy
281     && img->comps[0].prec == img->comps[1].prec
282     && img->comps[1].prec == img->comps[2].prec) {
283     /* -->> -->> -->> -->>
284     
285       24 bits color
286       
287     <<-- <<-- <<-- <<-- */
288     
289     f = fopen(outfile, "wb");
290     if (!f) {
291       fprintf(stderr, "failed to open %s for writing\n", outfile);
292       return 1;
293     }   
294     
295     w = img->comps[0].w;
296     wr = int_ceildivpow2(img->comps[0].w, img->comps[0].factor);
297     
298     h = img->comps[0].h;
299     hr = int_ceildivpow2(img->comps[0].h, img->comps[0].factor);
300     
301     fprintf(f, "BM");
302     
303     /* FILE HEADER */
304     /* ------------- */
305     fprintf(f, "%c%c%c%c",
306       (unsigned char) (hr * wr * 3 + 3 * hr * (wr % 2) +
307       54) & 0xff,
308       (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54)
309       >> 8) & 0xff,
310       (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54)
311       >> 16) & 0xff,
312       (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54)
313       >> 24) & 0xff);
314     fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff,
315       ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
316     fprintf(f, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,
317       ((54) >> 16) & 0xff, ((54) >> 24) & 0xff);
318     
319     /* INFO HEADER   */
320     /* ------------- */
321     fprintf(f, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff,
322       ((40) >> 16) & 0xff, ((40) >> 24) & 0xff);
323     fprintf(f, "%c%c%c%c", (unsigned char) ((wr) & 0xff),
324       (unsigned char) ((wr) >> 8) & 0xff,
325       (unsigned char) ((wr) >> 16) & 0xff,
326       (unsigned char) ((wr) >> 24) & 0xff);
327     fprintf(f, "%c%c%c%c", (unsigned char) ((hr) & 0xff),
328       (unsigned char) ((hr) >> 8) & 0xff,
329       (unsigned char) ((hr) >> 16) & 0xff,
330       (unsigned char) ((hr) >> 24) & 0xff);
331     fprintf(f, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff);
332     fprintf(f, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff);
333     fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff,
334       ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
335     fprintf(f, "%c%c%c%c",
336       (unsigned char) (3 * hr * wr +
337       3 * hr * (wr % 2)) & 0xff,
338       (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >>
339       8) & 0xff,
340       (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >>
341       16) & 0xff,
342       (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >>
343       24) & 0xff);
344     fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff,
345       ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
346     fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff,
347       ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff);
348     fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff,
349       ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
350     fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff,
351       ((0) >> 16) & 0xff, ((0) >> 24) & 0xff);
352     
353     for (i = 0; i < wr * hr; i++) {
354       unsigned char R, G, B;
355       /* a modifier */
356       // R = img->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
357       R = img->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
358       // G = img->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
359       G = img->comps[1].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
360       // B = img->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];
361       B = img->comps[2].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)];
362       fprintf(f, "%c%c%c", B, G, R);
363       
364       if ((i + 1) % wr == 0) {
365                                 for (pad = (3 * wr) % 4 ? 4 - (3 * wr) % 4 : 0; pad > 0; pad--) /* ADD */
366                                         fprintf(f, "%c", 0);
367       }
368     }
369     fclose(f);
370   }
371   return 0;
372 }