~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/codec/tmndec/store.c

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  1 /************************************************************************
  2  *
  3  *  store.c, picture output routines for tmndecode (H.263 decoder)
  4  *  Copyright (C) 1995, 1996  Telenor R&D, Norway
  5  *
  6  *  Contacts:
  7  *  Robert Danielsen                  <Robert.Danielsen@nta.no>
  8  *
  9  *  Telenor Research and Development  http://www.nta.no/brukere/DVC/
 10  *  P.O.Box 83                        tel.:   +47 63 84 84 00
 11  *  N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76
 12  *
 13  *  Copyright (C) 1997  University of BC, Canada
 14  *  Modified by: Michael Gallant <mikeg@ee.ubc.ca>
 15  *               Guy Cote <guyc@ee.ubc.ca>
 16  *               Berna Erol <bernae@ee.ubc.ca>
 17  *
 18  *  Contacts:
 19  *  Michael Gallant                   <mikeg@ee.ubc.ca>
 20  *
 21  *  UBC Image Processing Laboratory   http://www.ee.ubc.ca/image
 22  *  2356 Main Mall                    tel.: +1 604 822 4051
 23  *  Vancouver BC Canada V6T1Z4        fax.: +1 604 822 5949
 24  *
 25  ************************************************************************/
 26 
 27 /* Disclaimer of Warranty
 28  * 
 29  * These software programs are available to the user without any license fee
 30  * or royalty on an "as is" basis. The University of British Columbia
 31  * disclaims any and all warranties, whether express, implied, or
 32  * statuary, including any implied warranties or merchantability or of
 33  * fitness for a particular purpose.  In no event shall the
 34  * copyright-holder be liable for any incidental, punitive, or
 35  * consequential damages of any kind whatsoever arising from the use of
 36  * these programs.
 37  * 
 38  * This disclaimer of warranty extends to the user of these programs and
 39  * user's customers, employees, agents, transferees, successors, and
 40  * assigns.
 41  * 
 42  * The University of British Columbia does not represent or warrant that the
 43  * programs furnished hereunder are free of infringement of any
 44  * third-party patents.
 45  * 
 46  * Commercial implementations of H.263, including shareware, are subject to
 47  * royalty fees to patent holders.  Many of these patents are general
 48  * enough such that they are unavoidable regardless of implementation
 49  * design.
 50  * 
 51  */
 52 
 53 
 54 
 55 /* based on mpeg2decode, (C) 1994, MPEG Software Simulation Group and
 56  * mpeg2play, (C) 1994 Stefan Eckart <stefan@lis.e-technik.tu-muenchen.de>
 57  * 
 58  */
 59 
 60 
 61 #include <stdio.h>
 62 #include <stdlib.h>
 63 #include <string.h>
 64 #include <fcntl.h>
 65 #ifdef WIN32
 66 #include <io.h>
 67 #endif
 68 
 69 #include "config.h"
 70 #include "tmndec.h"
 71 #include "global.h"
 72 #ifdef WINDOWS
 73 int displayImage (unsigned char *lum, unsigned char *Cr, unsigned char *Cb);
 74 #endif
 75 
 76 /* private prototypes */
 77 static void store_yuv _ANSI_ARGS_ ((char *outname, unsigned char *src[],
 78                                      int offset, int incr, int height));
 79 static void store_yuv_append _ANSI_ARGS_ ((char *outname, unsigned char *src[],
 80                                       int offset, int incr, int height));
 81 static void store_sif _ANSI_ARGS_ ((char *outname, unsigned char *src[],
 82                                      int offset, int incr, int height));
 83 static void store_ppm_tga _ANSI_ARGS_ ((char *outname, unsigned char *src[],
 84                          int offset, int incr, int height, int tgaflag));
 85 static void store_yuv1 _ANSI_ARGS_ ((char *name, unsigned char *src,
 86                int offset, int incr, int width, int height, int append));
 87 static void putbyte _ANSI_ARGS_ ((int c));
 88 static void putword _ANSI_ARGS_ ((int w));
 89 static void conv422to444 _ANSI_ARGS_ ((unsigned char *src, unsigned char *dst));
 90 static void conv420to422 _ANSI_ARGS_ ((unsigned char *src, unsigned char *dst));
 91 
 92 #define OBFRSIZE 4096
 93 static unsigned char obfr[OBFRSIZE];
 94 static unsigned char *optr;
 95 static int outfile;
 96 
 97 /* store a picture as either one frame or two fields */
 98 void storeframe (unsigned char *src[], int frame)
 99 {
100   char outname[32];
101 
102   /* progressive */
103   sprintf (outname, outputname, frame, 'f');
104   store_one (outname, src, 0, coded_picture_width, vertical_size);
105 }
106 
107 /* store one frame or one field */
108 void store_one (char *outname, unsigned char *src[], int offset, int incr, int height)
109 {
110   switch (outtype)
111   {
112     case T_YUV:
113       store_yuv (outname, src, offset, incr, height);
114       break;
115     case T_YUV_CONC:
116       store_yuv_append (outname, src, offset, incr, height);
117       break;
118     case T_SIF:
119       store_sif (outname, src, offset, incr, height);
120       break;
121     case T_TGA:
122       store_ppm_tga (outname, src, offset, incr, height, 1);
123       break;
124     case T_PPM:
125       store_ppm_tga (outname, src, offset, incr, height, 0);
126       break;
127 #ifdef DISPLAY
128     case T_X11:
129       if (enhancement_layer_num == 1)
130         dither (src);
131       break;
132 #endif
133 #ifdef WINDOWS
134     case T_WIN:
135       if (enhancement_layer_num == 1)
136         displayImage (src[0], src[2], src[1]);
137       break;
138 #endif
139     default:
140       break;
141   }
142 }
143 
144 /* separate headerless files for y, u and v */
145 static void store_yuv (char *outname, unsigned char *src[], int offset, int incr, int height)
146 {
147   int hsize;
148   char tmpname[32];
149 
150   hsize = horizontal_size;
151 
152   sprintf (tmpname, "%s.Y", outname);
153   store_yuv1 (tmpname, src[0], offset, incr, hsize, height, 0);
154 
155   offset >>= 1;
156   incr >>= 1;
157   hsize >>= 1;
158   height >>= 1;
159 
160   sprintf (tmpname, "%s.U", outname);
161   store_yuv1 (tmpname, src[1], offset, incr, hsize, height, 0);
162 
163   sprintf (tmpname, "%s.V", outname);
164   store_yuv1 (tmpname, src[2], offset, incr, hsize, height, 0);
165 }
166 
167 /* concatenated headerless file for y, u and v */
168 static void store_yuv_append (outname, src, offset, incr, height)
169   char *outname;
170   unsigned char *src[];
171 int offset, incr, height;
172 {
173   int hsize;
174   hsize = horizontal_size;
175 
176   store_yuv1 (outname, src[0], offset, incr, hsize, height, 1);
177 
178   offset >>= 1;
179   incr >>= 1;
180   hsize >>= 1;
181   height >>= 1;
182 
183   store_yuv1 (outname, src[1], offset, incr, hsize, height, 1);
184   store_yuv1 (outname, src[2], offset, incr, hsize, height, 1);
185 }
186 
187 /* auxiliary routine */
188 static void store_yuv1 (char *name, unsigned char *src, int offset, 
189                         int incr, int width, int height, int append)
190 {
191   int i, j;
192   unsigned char *p;
193 
194   if (append)
195   {
196     if ((outfile = open (name, O_APPEND | O_WRONLY | O_BINARY, 0666)) == -1)
197     {
198       sprintf (errortext, "Couldn't append to %s\n", name);
199       error (errortext);
200     }
201   } else
202   {
203     if ((outfile = open (name, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666)) == -1)
204     {
205       sprintf (errortext, "Couldn't create %s\n", name);
206       error (errortext);
207     }
208   }
209 #if 0
210   if (!quiet)
211     fprintf (stderr, "saving %s\n", name);
212 #endif
213 
214   optr = obfr;
215 
216   for (i = 0; i < height; i++)
217   {
218     p = src + offset + incr * i;
219     for (j = 0; j < width; j++)
220       putbyte (*p++);
221   }
222 
223   if (optr != obfr)
224     write (outfile, obfr, optr - obfr);
225 
226   close (outfile);
227 }
228 
229 /* store as headerless file in U,Y,V,Y format */
230 static void store_sif (char *outname, unsigned char *src[], int offset, int incr, int height)
231 {
232   int i, j;
233   unsigned char *py, *pu, *pv;
234   static unsigned char *u422, *v422;
235 
236   if (!u422)
237   {
238     if (!(u422 = (unsigned char *) malloc ((coded_picture_width >> 1)
239                                            * coded_picture_height)))
240       error ("malloc failed");
241     if (!(v422 = (unsigned char *) malloc ((coded_picture_width >> 1)
242                                            * coded_picture_height)))
243       error ("malloc failed");
244   }
245   conv420to422 (src[1], u422);
246   conv420to422 (src[2], v422);
247 
248   strcat (outname, ".SIF");
249 
250   if (!quiet)
251     fprintf (stderr, "saving %s\n", outname);
252 
253   if ((outfile = open (outname, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666)) == -1)
254   {
255     sprintf (errortext, "Couldn't create %s\n", outname);
256     error (errortext);
257   }
258   optr = obfr;
259 
260   for (i = 0; i < height; i++)
261   {
262     py = src[0] + offset + incr * i;
263     pu = u422 + (offset >> 1) + (incr >> 1) * i;
264     pv = v422 + (offset >> 1) + (incr >> 1) * i;
265 
266     for (j = 0; j < horizontal_size; j += 2)
267     {
268       putbyte (*pu++);
269       putbyte (*py++);
270       putbyte (*pv++);
271       putbyte (*py++);
272     }
273   }
274 
275   if (optr != obfr)
276     write (outfile, obfr, optr - obfr);
277 
278   close (outfile);
279 }
280 
281 /* store as PPM (PBMPLUS) or uncompressed Truevision TGA ('Targa') file */
282 static void store_ppm_tga (char *outname, unsigned char *src[], int offset, int incr, 
283                            int height, int tgaflag)
284 {
285   int i, j;
286   int y, u, v, r, g, b;
287   int crv, cbu, cgu, cgv;
288   unsigned char *py, *pu, *pv;
289   static unsigned char tga24[14] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 32};
290   char header[32];
291   static unsigned char *u422, *v422, *u444, *v444;
292 
293   if (!u444)
294   {
295     if (!(u422 = (unsigned char *) malloc ((coded_picture_width >> 1)
296                                            * coded_picture_height)))
297       error ("malloc failed");
298     if (!(v422 = (unsigned char *) malloc ((coded_picture_width >> 1)
299                                            * coded_picture_height)))
300       error ("malloc failed");
301 
302     if (!(u444 = (unsigned char *) malloc (coded_picture_width
303                                            * coded_picture_height)))
304       error ("malloc failed");
305 
306     if (!(v444 = (unsigned char *) malloc (coded_picture_width
307                                            * coded_picture_height)))
308       error ("malloc failed");
309   }
310   conv420to422 (src[1], u422);
311   conv420to422 (src[2], v422);
312   conv422to444 (u422, u444);
313   conv422to444 (v422, v444);
314 
315   strcat (outname, tgaflag ? ".tga" : ".ppm");
316 
317   if (!quiet)
318     fprintf (stderr, "saving %s\n", outname);
319 
320   if ((outfile = open (outname, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666)) == -1)
321   {
322     sprintf (errortext, "Couldn't create %s\n", outname);
323     error (errortext);
324   }
325   optr = obfr;
326 
327   if (tgaflag)
328   {
329     /* TGA header */
330     for (i = 0; i < 12; i++)
331       putbyte (tga24[i]);
332 
333     putword (horizontal_size);
334     putword (height);
335     putbyte (tga24[12]);
336     putbyte (tga24[13]);
337   } else
338   {
339     /* PPM header */
340     sprintf (header, "P6\n%d %d\n255\n", horizontal_size, height);
341 
342     for (i = 0; header[i] != 0; i++)
343       putbyte (header[i]);
344   }
345 
346   /* matrix coefficients */
347   crv = convmat[matrix_coefficients][0];
348   cbu = convmat[matrix_coefficients][1];
349   cgu = convmat[matrix_coefficients][2];
350   cgv = convmat[matrix_coefficients][3];
351 
352   for (i = 0; i < height; i++)
353   {
354     py = src[0] + offset + incr * i;
355     pu = u444 + offset + incr * i;
356     pv = v444 + offset + incr * i;
357 
358     for (j = 0; j < horizontal_size; j++)
359     {
360       u = *pu++ - 128;
361       v = *pv++ - 128;
362       y = 76309 * (*py++ - 16); /* (255/219)*65536 */
363       r = clp[(y + crv * v + 32768) >> 16];
364       g = clp[(y - cgu * u - cgv * v + 32768) >> 16];
365       b = clp[(y + cbu * u + 32786) >> 16];
366 
367       if (tgaflag)
368       {
369         putbyte (b);
370         putbyte (g);
371         putbyte (r);
372       } else
373       {
374         putbyte (r);
375         putbyte (g);
376         putbyte (b);
377       }
378     }
379   }
380 
381   if (optr != obfr)
382     write (outfile, obfr, optr - obfr);
383 
384   close (outfile);
385 }
386 
387 static void putbyte (int c)
388 {
389   *optr++ = c;
390 
391   if (optr == obfr + OBFRSIZE)
392   {
393     write (outfile, obfr, OBFRSIZE);
394     optr = obfr;
395   }
396 }
397 
398 static void putword (int w)
399 {
400   putbyte (w);
401   putbyte (w >> 8);
402 }
403 
404 /* horizontal 1:2 interpolation filter */
405 static void conv422to444 (unsigned char *src, unsigned char *dst)
406 {
407   int i, i2, w, j, im3, im2, im1, ip1, ip2, ip3;
408 
409   w = coded_picture_width >> 1;
410 
411   for (j = 0; j < coded_picture_height; j++)
412   {
413     for (i = 0; i < w; i++)
414     {
415 
416       i2 = i << 1;
417       im3 = (i < 3) ? 0 : i - 3;
418       im2 = (i < 2) ? 0 : i - 2;
419       im1 = (i < 1) ? 0 : i - 1;
420       ip1 = (i < w - 1) ? i + 1 : w - 1;
421       ip2 = (i < w - 2) ? i + 2 : w - 1;
422       ip3 = (i < w - 3) ? i + 3 : w - 1;
423 
424       /* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */
425       dst[i2] = clp[(int) (5 * src[im3]
426                            - 21 * src[im2]
427                            + 70 * src[im1]
428                            + 228 * src[i]
429                            - 37 * src[ip1]
430                            + 11 * src[ip2] + 128) >> 8];
431 
432       dst[i2 + 1] = clp[(int) (5 * src[ip3]
433                                - 21 * src[ip2]
434                                + 70 * src[ip1]
435                                + 228 * src[i]
436                                - 37 * src[im1]
437                                + 11 * src[im2] + 128) >> 8];
438     }
439     src += w;
440     dst += coded_picture_width;
441   }
442 }
443 
444 /* vertical 1:2 interpolation filter */
445 static void conv420to422 (unsigned char *src, unsigned char *dst)
446 {
447   int w, h, i, j, j2;
448   int jm3, jm2, jm1, jp1, jp2, jp3;
449 
450   w = coded_picture_width >> 1;
451   h = coded_picture_height >> 1;
452 
453   /* intra frame */
454   for (i = 0; i < w; i++)
455   {
456     for (j = 0; j < h; j++)
457     {
458       j2 = j << 1;
459       jm3 = (j < 3) ? 0 : j - 3;
460       jm2 = (j < 2) ? 0 : j - 2;
461       jm1 = (j < 1) ? 0 : j - 1;
462       jp1 = (j < h - 1) ? j + 1 : h - 1;
463       jp2 = (j < h - 2) ? j + 2 : h - 1;
464       jp3 = (j < h - 3) ? j + 3 : h - 1;
465 
466       /* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */
467       /* New FIR filter coefficients (*256): 3 -16 67 227 -32 7 */
468       dst[w * j2] = clp[(int) (3 * src[w * jm3]
469                                - 16 * src[w * jm2]
470                                + 67 * src[w * jm1]
471                                + 227 * src[w * j]
472                                - 32 * src[w * jp1]
473                                + 7 * src[w * jp2] + 128) >> 8];
474 
475       dst[w * (j2 + 1)] = clp[(int) (3 * src[w * jp3]
476                                      - 16 * src[w * jp2]
477                                      + 67 * src[w * jp1]
478                                      + 227 * src[w * j]
479                                      - 32 * src[w * jm1]
480                                      + 7 * src[w * jm2] + 128) >> 8];
481     }
482     src++;
483     dst++;
484   }
485 }
486 
487 /* Stores 1 frame to a file in a raw format */
488 
489 void save_frame (unsigned char *src[], int framenum, FILE *file)
490 {
491   unsigned char *lum;
492   unsigned char *Cr;
493   unsigned char *Cb;
494 
495   lum = src[0];
496   Cb = src[1];
497   Cr = src[2];
498 
499   if ((int) fwrite (lum, sizeof (unsigned char), coded_picture_height * coded_picture_width,
500                     file) != coded_picture_height * coded_picture_width)
501   {
502     fprintf (stdout, "Error occured when writing reconstructed data\n");
503     exit (-1);
504   }
505   if ((int) fwrite (Cb, sizeof (unsigned char), coded_picture_height * coded_picture_width / 4,
506                  file) != coded_picture_height * coded_picture_width / 4)
507   {
508     fprintf (stdout, "Error occured when writing reconstructed data\n");
509     exit (-1);
510   }
511   if ((int) fwrite (Cr, sizeof (unsigned char), coded_picture_height * coded_picture_width / 4,
512                  file) != coded_picture_height * coded_picture_width / 4)
513   {
514     fprintf (stdout, "Error occured when writing reconstructed data\n");
515     exit (-1);
516   }
517 }
518 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.