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

  1. /* yuvsplittoppm.c - construct a portable pixmap from 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 have been scaled again
  8. ** to fit into the smaller range of values for this standard.
  9. **
  10. ** by Marcel Wijkstra <wijkstra@fwi.uva.nl>
  11. **
  12. ** Based on ppmtoyuvsplit.c
  13. **
  14. ** Permission to use, copy, modify, and distribute this software and its
  15. ** documentation for any purpose and without fee is hereby granted, provided
  16. ** that the above copyright notice appear in all copies and that both that
  17. ** copyright notice and this permission notice appear in supporting
  18. ** documentation.  This software is provided "as is" without express or
  19. ** implied warranty.
  20. */
  21.  
  22. #include "ppm.h"
  23.  
  24. /* x must be signed for the following to work correctly */
  25. #define limit(x) (((x>0xffffff)?0xff0000:((x<=0xffff)?0:x&0xff0000))>>16)
  26.  
  27. int
  28. main(argc, argv)
  29. char **argv;
  30. {
  31.     FILE *ifp,*vf,*uf,*yf;
  32.     pixel          *pixelrow1,*pixelrow2;
  33.     register pixel *pP1,*pP2;
  34.     int             rows, cols, format, row;
  35.     register int    col;
  36.     pixval          maxval;
  37.     char        *usage="<basename> <width> <height> [-ccir601]";
  38.     long int  y,u,v,y0,y1,y2,y3,u0,u1,u2,u3,v0,v1,v2,v3;
  39.     unsigned char  *y1buf,*y2buf,*ubuf,*vbuf;
  40.     char         ufname[256],vfname[256],yfname[256];
  41. /* Whether to create YUV in JFIF(JPEG) or CCIR.601(MPEG) scale */
  42.     int        ccir601=0;
  43.  
  44.  
  45.     ppm_init(&argc, argv);
  46.  
  47.     if ((argc>5) || (argc<4)) pm_usage(usage);
  48.  
  49.         if (argc==5)
  50.                 if (!strncmp(argv[4],"-c",2))
  51.                         ccir601 = 1;
  52.         else
  53.             pm_usage(usage);
  54.  
  55.     strcpy(ufname,argv[1]);
  56.     strcpy(vfname,argv[1]);
  57.     strcpy(yfname,argv[1]);
  58.  
  59.     strcat(ufname,".U");
  60.     strcat(vfname,".V");
  61.     strcat(yfname,".Y");
  62.  
  63.     uf = fopen(ufname,"rb");
  64.     vf = fopen(vfname,"rb");
  65.     yf = fopen(yfname,"rb");
  66.  
  67.     if(!(uf && vf && yf)) {
  68.       perror("error opening input files");
  69.       exit(0);
  70.     }
  71.  
  72.         cols = atoi(argv[2]);
  73.         rows = atoi(argv[3]);
  74.         if (cols <= 0 || rows <= 0)
  75.                 pm_usage(usage);
  76.  
  77.         ppm_writeppminit(stdout, cols, rows, (pixval) 255, 0);
  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.         fread(y1buf, (cols & ~1), 1, yf);
  98.         fread(y2buf, (cols & ~1), 1, yf);
  99.         fread(ubuf, cols/2, 1, uf);
  100.         fread(vbuf, cols/2, 1, vf);
  101.  
  102.         y1ptr = y1buf; y2ptr = y2buf; vptr = vbuf; uptr = ubuf;
  103.  
  104.                 pP1 = pixelrow1; pP2 = pixelrow2;
  105.  
  106.         for (col = 0 ; col < (cols & ~1); col += 2) {
  107.             long int r0,g0,b0,r1,g1,b1,r2,g2,b2,r3,g3,b3;
  108.  
  109.             y0 = (long int) *y1ptr++;
  110.             y1 = (long int) *y1ptr++;
  111.             y2 = (long int) *y2ptr++;
  112.             y3 = (long int) *y2ptr++;
  113.  
  114.             u = (long int) ((*uptr++) - 128);
  115.             v = (long int) ((*vptr++) - 128);
  116.  
  117.             if (ccir601) {
  118.                 y0 = ((y0-16)*255)/219;
  119.                 y1 = ((y1-16)*255)/219;
  120.                 y2 = ((y2-16)*255)/219;
  121.                 y3 = ((y3-16)*255)/219;
  122.  
  123.                 u  = (u*255)/224 ;
  124.                 v  = (v*255)/224 ;
  125.             }
  126.             /* mean the chroma for subsampling */
  127.  
  128.             u0=u1=u2=u3=u;
  129.             v0=v1=v2=v3=v;
  130.  
  131.  
  132. /* The inverse of the JFIF RGB to YUV Matrix for $00010000 = 1.0
  133.  
  134. [Y]   [65496        0   91880][R]
  135. [U] = [65533   -22580  -46799[G]
  136. [V]   [65537   116128      -8][B]
  137.  
  138. */
  139.  
  140.             r0 = 65536 * y0               + 91880 * v0;
  141.             g0 = 65536 * y0 -  22580 * u0 - 46799 * v0;
  142.                         b0 = 65536 * y0 + 116128 * u0             ;
  143.  
  144.             r1 = 65536 * y1               + 91880 * v1;
  145.             g1 = 65536 * y1 -  22580 * u1 - 46799 * v1;
  146.                         b1 = 65536 * y1 + 116128 * u1             ;
  147.  
  148.             r2 = 65536 * y2               + 91880 * v2;
  149.             g2 = 65536 * y2 -  22580 * u2 - 46799 * v2;
  150.                         b2 = 65536 * y2 + 116128 * u2             ;
  151.  
  152.             r3 = 65536 * y3               + 91880 * v3;
  153.             g3 = 65536 * y3 -  22580 * u3 - 46799 * v3;
  154.                         b3 = 65536 * y3 + 116128 * u3             ;
  155.  
  156.             r0 = limit(r0);
  157.             r1 = limit(r1);
  158.             r2 = limit(r2);
  159.             r3 = limit(r3);
  160.             g0 = limit(g0);
  161.             g1 = limit(g1);
  162.             g2 = limit(g2);
  163.             g3 = limit(g3);
  164.             b0 = limit(b0);
  165.             b1 = limit(b1);
  166.             b2 = limit(b2);
  167.             b3 = limit(b3);
  168.  
  169.             /* first pixel */
  170.             PPM_ASSIGN(*pP1, (pixval)r0, (pixval)g0, (pixval)b0);
  171.             pP1++;
  172.             /* 2nd pixval */
  173.             PPM_ASSIGN(*pP1, (pixval)r1, (pixval)g1, (pixval)b1);
  174.             pP1++;
  175.             /* 3rd pixval */
  176.             PPM_ASSIGN(*pP2, (pixval)r2, (pixval)g2, (pixval)b2);
  177.             pP2++;
  178.             /* 4th pixval */
  179.             PPM_ASSIGN(*pP2, (pixval)r3, (pixval)g3, (pixval)b3);
  180.             pP2++;
  181.         }
  182.         ppm_writeppmrow(stdout, pixelrow1, cols, (pixval) 255, 0);
  183.         ppm_writeppmrow(stdout, pixelrow2, cols, (pixval) 255, 0);
  184.     }
  185.     pm_close(stdout);
  186.  
  187.         fclose(yf);
  188.     fclose(uf);
  189.     fclose(vf);
  190.     exit(0);
  191. }
  192.