home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / ppm / yuvtoppm.c < prev   
C/C++ Source or Header  |  1993-10-04  |  3KB  |  103 lines

  1. /* yuvtoppm.c - convert Abekas YUV bytes into a portable pixmap
  2. **
  3. ** by Marc Boucher
  4. ** Internet: marc@PostImage.COM
  5. ** 
  6. ** Based on Example Conversion Program, A60/A64 Digital Video Interface
  7. ** Manual, page 69
  8. **
  9. ** Uses integer arithmetic rather than floating point for better performance
  10. **
  11. ** Copyright (C) 1991 by DHD PostImage Inc.
  12. ** Copyright (C) 1987 by Abekas Video Systems Inc.
  13. ** Copyright (C) 1991 by Jef Poskanzer.
  14. **
  15. ** Permission to use, copy, modify, and distribute this software and its
  16. ** documentation for any purpose and without fee is hereby granted, provided
  17. ** that the above copyright notice appear in all copies and that both that
  18. ** copyright notice and this permission notice appear in supporting
  19. ** documentation.  This software is provided "as is" without express or
  20. ** implied warranty.
  21. */
  22.  
  23. #include "ppm.h"
  24.  
  25. /* x must be signed for the following to work correctly */
  26. #define limit(x) (((x>0xffffff)?0xff0000:((x<=0xffff)?0:x&0xff0000))>>16)
  27.  
  28. int
  29. main(argc, argv)
  30.     char          **argv;
  31. {
  32.     FILE           *ifp;
  33.     pixel          *pixrow;
  34.     int             argn, rows, cols, row, i;
  35.     char           *usage = "<width> <height> [yuvfile]";
  36.     long  *yuvbuf;
  37.  
  38.  
  39.     ppm_init(&argc, argv);
  40.  
  41.     argn = 1;
  42.  
  43.     if (argn + 2 > argc)
  44.         pm_usage(usage);
  45.  
  46.     cols = atoi(argv[argn++]);
  47.     rows = atoi(argv[argn++]);
  48.     if (cols <= 0 || rows <= 0)
  49.         pm_usage(usage);
  50.  
  51.     if (argn < argc) {
  52.         ifp = pm_openr(argv[argn]);
  53.         ++argn;
  54.     } else
  55.         ifp = stdin;
  56.  
  57.     if (argn != argc)
  58.         pm_usage(usage);
  59.  
  60.     if (255 > PGM_MAXMAXVAL)
  61.         pm_error(
  62.       "maxval of 255 is too large - try recompiling with a larger pixval type");
  63.  
  64.     ppm_writeppminit(stdout, cols, rows, (pixval) 255, 0);
  65.     pixrow = ppm_allocrow(cols);
  66.     yuvbuf = (long *) pm_allocrow(cols, 2);
  67.  
  68.     for (row = 0; row < rows; ++row) {
  69.         long   tmp, y, u, v, y1, r, g, b, *yuvptr;
  70.         register pixel *pP;
  71.         register int    col;
  72.  
  73.         fread(yuvbuf, cols * 2, 1, ifp);
  74.  
  75.         for (col = 0, pP = pixrow, yuvptr = yuvbuf; col < cols; col += 2) {
  76.             tmp = *yuvptr++;
  77.             u = (0xff & (tmp >> 24)) - 128;
  78.             y = ((0xff & (tmp >> 16)) - 16);
  79.             if (y < 0) y = 0;
  80.  
  81.             v = (0xff & (tmp >> 8)) - 128;
  82.             y1 = ((0xff & tmp) - 16);
  83.             if (y1 < 0) y1 = 0;
  84.  
  85.             r = 104635 * v;
  86.             g = -25690 * u + -53294 * v;
  87.             b = 132278 * u;
  88.  
  89.             y*=76310; y1*=76310;
  90.  
  91.             PPM_ASSIGN(*pP, limit(r+y), limit(g+y), limit(b+y));
  92.             pP++;
  93.             PPM_ASSIGN(*pP, limit(r+y1), limit(g+y1), limit(b+y1));
  94.             pP++;
  95.         }
  96.         ppm_writeppmrow(stdout, pixrow, cols, (pixval) 255, 0);
  97.     }
  98.     pm_close(ifp);
  99.     pm_close(stdout);
  100.  
  101.     exit(0);
  102. }
  103.