home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / ppm / ppmtoyuvsplit.c < prev    next >
C/C++ Source or Header  |  1993-10-14  |  6KB  |  197 lines

  1. /* ppmtoyuvsplit.c - convert a portable pixmap into 3 raw files:
  2. ** - basename.Y : The Luminance chunk at the size of the Image
  3. ** - basename.U : The Chrominance chunk U at 1/4
  4. ** - basename.V : The Chrominance chunk V at 1/4
  5. ** The subsampled U and V values are made by arithmetic mean.
  6. **
  7. ** If CCIR601 is defined, the produced YUV triples are scaled again
  8. ** to fit into the smaller range of values for this standard.
  9. **
  10. ** by A.Beck
  11. ** Internet: Andre_Beck@IRS.Inf.TU-Dresden.de
  12. **
  13. ** Based on ppmtoyuv.c
  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. /* Wether to create YUV in JFIF(JPEG) or CCIR.601(MPEG) scale */
  24. #define CCIR601
  25.  
  26. /* Wether to use pm_close() or fake it -- don't ask me why */
  27. /* #define ORIGINAL */
  28.  
  29. /* ALPHA Kludge by Franky */
  30.  
  31. #ifdef __alpha
  32. #define myLONG int
  33. #else
  34. #define myLONG long
  35. #endif
  36.  
  37. #include "ppm.h"
  38.  
  39. int
  40. main(argc, argv)
  41. char **argv;
  42. {
  43.         FILE *ifp,*vf,*uf,*yf;
  44.         pixel          *pixelrow1,*pixelrow2;
  45.         register pixel *pP1,*pP2;
  46.         int             rows, cols, format, row;
  47.         register int    col;
  48.         pixval          maxval;
  49.         myLONG y,u,v,y0,y1,y2,y3,u0,u1,u2,u3,v0,v1,v2,v3;
  50.         unsigned char  *y1buf,*y2buf,*ubuf,*vbuf;
  51.         char            ufname[256],vfname[256],yfname[256];
  52.  
  53.  
  54.         ppm_init(&argc, argv);
  55.  
  56.         if ((argc>3)||(argc<2)) pm_usage("basename [ppmfile]");
  57.  
  58.         if (argc == 3) ifp = pm_openr(argv[2]);
  59.         else ifp = stdin;
  60.  
  61.         strcpy(ufname,argv[1]);
  62.         strcpy(vfname,argv[1]);
  63.         strcpy(yfname,argv[1]);
  64.  
  65.         strcat(ufname,".U");
  66.         strcat(vfname,".V");
  67.         strcat(yfname,".Y");
  68.  
  69.         uf = fopen(ufname,"wb");
  70.         vf = fopen(vfname,"wb");
  71.         yf = fopen(yfname,"wb");
  72.  
  73.         if(!(uf && vf && yf)) {
  74.          perror("error opening output files");
  75.          exit(0);
  76.         }
  77.         ppm_readppminit(ifp, &cols, &rows, &maxval, &format);
  78.  
  79.         if(cols & 1) fprintf(stderr,
  80.                              "%s: Warning: odd columns count, exceed ignored\n",
  81.                              argv[0]);
  82.         if(rows & 1) fprintf(stderr,
  83.                              "%s: Warning: odd rows count, exceed ignored\n",
  84.                              argv[0]);
  85.  
  86.         pixelrow1 = ((pixel*) pm_allocrow( cols, sizeof(pixel) ));
  87.         pixelrow2 = ((pixel*) pm_allocrow( cols, sizeof(pixel) ));
  88.  
  89.         y1buf = (unsigned char *) pm_allocrow( cols, 1 );
  90.         y2buf = (unsigned char *) pm_allocrow( cols, 1 );
  91.         ubuf = (unsigned char *) pm_allocrow( cols, 1 );
  92.         vbuf = (unsigned char *) pm_allocrow( cols, 1 );
  93.  
  94.         for (row = 0; row < (rows & ~1); row += 2) {
  95.                 unsigned char *y1ptr,*y2ptr,*uptr,*vptr;
  96.  
  97.                 ppm_readppmrow(ifp, pixelrow1, cols, maxval, format);
  98.                 ppm_readppmrow(ifp, pixelrow2, cols, maxval, format);
  99.  
  100.                 pP1 = pixelrow1; pP2 = pixelrow2;
  101.                 y1ptr = y1buf; y2ptr = y2buf; vptr = vbuf; uptr = ubuf;
  102.  
  103.                 for (col = 0 ; col < (cols & ~1); col += 2) {
  104.                         pixval r0,g0,b0,r1,g1,b1,r2,g2,b2,r3,g3,b3;
  105.  
  106.                         /* first pixel */
  107.                         r0 = PPM_GETR(*pP1);
  108.                         g0 = PPM_GETG(*pP1);
  109.                         b0 = PPM_GETB(*pP1);
  110.                         pP1++;
  111.                         /* 2nd pixel */
  112.                         r1 = PPM_GETR(*pP1);
  113.                         g1 = PPM_GETG(*pP1);
  114.                         b1 = PPM_GETB(*pP1);
  115.                         pP1++;
  116.                         /* 3rd pixel */
  117.                         r2 = PPM_GETR(*pP2);
  118.                         g2 = PPM_GETG(*pP2);
  119.                         b2 = PPM_GETB(*pP2);
  120.                         pP2++;
  121.                         /* 4th pixel */
  122.                         r3 = PPM_GETR(*pP2);
  123.                         g3 = PPM_GETG(*pP2);
  124.                         b3 = PPM_GETB(*pP2);
  125.                         pP2++;
  126.  
  127.  
  128. /* The JFIF RGB to YUV Matrix for $00010000 = 1.0
  129.  
  130. [Y]   [19595   38469    7471][R]
  131. [U] = [-11056  -21712  32768][G]
  132. [V]   [32768   -27440  -5328][B]
  133.  
  134. */
  135.  
  136.                         y0 =  19595 * r0 + 38469 * g0 +  7471 * b0;
  137.                         u0 = -11056 * r0 - 21712 * g0 + 32768 * b0;
  138.                         v0 =  32768 * r0 - 27440 * g0 -  5328 * b0;
  139.  
  140.                         y1 =  19595 * r1 + 38469 * g1 +  7471 * b1;
  141.                         u1 = -11056 * r1 - 21712 * g1 + 32768 * b1;
  142.                         v1 =  32768 * r1 - 27440 * g1 -  5328 * b1;
  143.  
  144.                         y2 =  19595 * r2 + 38469 * g2 +  7471 * b2;
  145.                         u2 = -11056 * r2 - 21712 * g2 + 32768 * b2;
  146.                         v2 =  32768 * r2 - 27440 * g2 -  5328 * b2;
  147.  
  148.                         y3 =  19595 * r3 + 38469 * g3 +  7471 * b3;
  149.                         u3 = -11056 * r3 - 21712 * g3 + 32768 * b3;
  150.                         v3 =  32768 * r3 - 27440 * g3 -  5328 * b3;
  151.  
  152.                         /* mean the chroma for subsampling */
  153.  
  154.                         u  = (u0+u1+u2+u3)>>2;
  155.                         v  = (v0+v1+v2+v3)>>2;
  156.  
  157. #ifdef CCIR601
  158.  
  159.                         y0 = (y0 * 219)/255 + 1048576;
  160.                         y1 = (y1 * 219)/255 + 1048576;
  161.                         y2 = (y2 * 219)/255 + 1048576;
  162.                         y3 = (y3 * 219)/255 + 1048576;
  163.  
  164.                         u  = (u * 224)/255 ;
  165.                         v  = (v * 224)/255 ;
  166. #endif
  167.  
  168.  
  169.                         *y1ptr++  = (y0 >> 16) ;
  170.                         *y1ptr++  = (y1 >> 16) ;
  171.                         *y2ptr++  = (y2 >> 16) ;
  172.                         *y2ptr++  = (y3 >> 16) ;
  173.  
  174.  
  175.                         *uptr++   = (u >> 16)+128 ;
  176.                         *vptr++   = (v >> 16)+128 ;
  177.  
  178.                 }
  179.                 fwrite(y1buf, (cols & ~1), 1, yf);
  180.                 fwrite(y2buf, (cols & ~1), 1, yf);
  181.                 fwrite(ubuf, cols/2, 1, uf);
  182.                 fwrite(vbuf, cols/2, 1, vf);
  183.         }
  184.  
  185. /* I dunno why pm_close sees an error... get rid of it */
  186.  
  187. #ifdef ORIGINAL
  188.         pm_close(ifp);
  189. #else
  190.         if(ifp != stdin) fclose(ifp);
  191. #endif
  192.         fclose(yf);
  193.         fclose(uf);
  194.         fclose(vf);
  195.         exit(0);
  196. }
  197.