home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 9 / CD_ASCQ_09_1193.iso / news / 4441 / mpegcode / misc / ppmtoyuv.c < prev    next >
C/C++ Source or Header  |  1993-01-01  |  7KB  |  300 lines

  1. /*===========================================================================*
  2.  * ppmtoyuv.c                                     *
  3.  *                                         *
  4.  *    program to convert ppm file to yuv file                     *
  5.  *                                         *
  6.  *===========================================================================*/
  7.  
  8. /*
  9.  * Copyright (c) 1993 The Regents of the University of California.
  10.  * All rights reserved.
  11.  *
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose, without fee, and without written agreement is
  14.  * hereby granted, provided that the above copyright notice and the following
  15.  * two paragraphs appear in all copies of this software.
  16.  *
  17.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  18.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  19.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  20.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  21.  *
  22.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  23.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  24.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  25.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  26.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  27.  */
  28.  
  29. /*  
  30.  *  $Header: /n/picasso/users/keving/encode/src/RCS/readframe.c,v 1.1 1993/07/22 22:23:43 keving Exp keving $
  31.  *  $Log: readframe.c,v $
  32.  * Revision 1.1  1993/07/22  22:23:43  keving
  33.  * nothing
  34.  *
  35.  */
  36.  
  37.  
  38. /*==============*
  39.  * HEADER FILES *
  40.  *==============*/
  41.  
  42. #include <stdio.h>
  43. #include "ansi.h"
  44.  
  45.  
  46. typedef    unsigned char uint8;
  47. typedef char int8;
  48. typedef int boolean;
  49. #define TRUE 1
  50. #define FALSE 0
  51.  
  52.  
  53. int        height, width;
  54. uint8   **ppm_data;
  55. uint8 **orig_y, **orig_cr, **orig_cb;
  56.  
  57.  
  58. /*===============================*
  59.  * INTERNAL PROCEDURE prototypes *
  60.  *===============================*/
  61.  
  62. static int  ReadNextInteger _ANSI_ARGS_((FILE *fpointer));
  63. static boolean    ReadPPM _ANSI_ARGS_((FILE *fpointer));
  64. static void WriteYUV _ANSI_ARGS_((FILE *fpointer));
  65. static void PPMtoYUV _ANSI_ARGS_((void));
  66.  
  67.  
  68. void    main(int argc, char **argv)
  69. {
  70.     if ( ! ReadPPM(stdin) )
  71.     {
  72.     fprintf(stderr, "Error reading PPM input file!!!\n");
  73.     exit(1);
  74.     }
  75.  
  76.     PPMtoYUV();
  77.  
  78.     WriteYUV(stdout);
  79. }
  80.  
  81.  
  82. static boolean    ReadPPM(FILE *fpointer)
  83. {
  84.     char    input[256];
  85.     uint8   junk[4096];
  86.     register int y;
  87.     int  maxVal;
  88.  
  89.     if ( fread(input, sizeof(char), 2, fpointer) != 2 )
  90.     return FALSE;
  91.  
  92.     if ( strncmp(input, "P6", 2) != 0 )        /* magic number */
  93.     return FALSE;
  94.  
  95.     width = ReadNextInteger(fpointer);
  96.     if ( width == -1 )
  97.         return FALSE;
  98.  
  99.     height = ReadNextInteger(fpointer);
  100.     if ( height == -1 )
  101.     return FALSE;
  102.  
  103.     maxVal = ReadNextInteger(fpointer);
  104.     if ( maxVal == -1 )
  105.     return FALSE;
  106.  
  107.     if ( maxVal != 255 )
  108.     {
  109.     fprintf(stdout, "MAXVAL != 255!!!  Exiting!\n");
  110.     exit(1);
  111.     }
  112.  
  113.     ppm_data = (uint8 **) malloc(sizeof(uint8 *) * height);
  114.  
  115.     for ( y = 0; y < height; y++ )
  116.     {
  117.         ppm_data[y] = (uint8 *) malloc(3*sizeof(uint8) * width);
  118.     }
  119.  
  120.     for ( y = 0; y < height; y++ )
  121.     {
  122.     fread(ppm_data[y], sizeof(char), 3*width, fpointer);
  123.  
  124.     /* read the leftover stuff on the right side */
  125.     fread(junk, sizeof(char), 3*(width-width), fpointer);
  126.     }
  127.  
  128.     return TRUE;
  129. }
  130.  
  131.  
  132. /*=====================*
  133.  * INTERNAL PROCEDURES *
  134.  *=====================*/
  135.  
  136. static int    ReadNextInteger(FILE *fpointer)
  137. {
  138.     char    input[256];
  139.     int        index;
  140.  
  141.     /* skip whitespace */
  142.     while ( fgets(input, 2, fpointer) != NULL )
  143.     {
  144.     if ( isspace(input[0]) )
  145.         continue;
  146.  
  147.     /* read rest of integer */
  148.     index = 1;
  149.     while ( fgets(&input[index], 2, fpointer) != NULL )
  150.     {
  151.         if ( isspace(input[index]) )
  152.         break;
  153.         index++;
  154.     }
  155.     input[index] = '\0';
  156.  
  157.     return atoi(input);
  158.     }
  159.  
  160.     return -1;        /* end of file reached */
  161. }
  162.  
  163.  
  164.  
  165. /*===========================================================================*
  166.  *
  167.  * PPMtoYUV
  168.  *
  169.  *    convert PPM data into YUV data
  170.  *    assumes that ydivisor = 1
  171.  *
  172.  * RETURNS:    nothing
  173.  *
  174.  * SIDE EFFECTS:    none
  175.  *
  176.  *===========================================================================*/
  177. void PPMtoYUV()
  178. {
  179.     register int x, y;
  180.     register uint8 *dy0, *dy1;
  181.     register uint8 *dcr, *dcb;
  182.     register uint8 *src0, *src1;
  183.     register int cdivisor;
  184.     static boolean  first = TRUE;
  185.     static float  mult299[1024], mult587[1024], mult114[1024];
  186.     static float  mult16874[1024], mult33126[1024], mult5[1024];
  187.     static float mult41869[1024], mult08131[1024];
  188.  
  189.     if ( first )
  190.     {
  191.         register int index;
  192.     register int maxValue;
  193.  
  194.     maxValue = 255;
  195.  
  196.         for ( index = 0; index <= maxValue; index++ )
  197.     {
  198.         mult299[index] = index*0.29900;
  199.         mult587[index] = index*0.58700;
  200.         mult114[index] = index*0.11400;
  201.         mult16874[index] = -0.16874*index;
  202.         mult33126[index] = -0.33126*index;
  203.         mult5[index] = index*0.50000;
  204.         mult41869[index] = -0.41869*index;
  205.         mult08131[index] = -0.08131*index;
  206.     }
  207.     
  208.     first = FALSE;
  209.     }
  210.  
  211.     orig_y = (uint8 **) malloc(sizeof(uint8 *) * height);
  212.     for (y = 0; y < height; y++) {
  213.         orig_y[y] = (uint8 *) malloc(sizeof(uint8) * width);
  214.     }
  215.  
  216.     orig_cr = (uint8 **) malloc(sizeof(int8 *) * height / 2);
  217.     for (y = 0; y < height / 2; y++) {
  218.         orig_cr[y] = (uint8 *) malloc(sizeof(int8) * width / 2);
  219.     }
  220.  
  221.     orig_cb = (uint8 **) malloc(sizeof(int8 *) * height / 2);
  222.     for (y = 0; y < height / 2; y++) {
  223.         orig_cb[y] = (uint8 *) malloc(sizeof(int8) * width / 2);
  224.     }
  225.  
  226.     /* assume ydivisor = 1, so cdivisor = 4 */
  227.     cdivisor = 4;
  228.  
  229.     for (y = 0; y < height; y += 2)
  230.     {
  231.     src0 = ppm_data[y];
  232.     src1 = ppm_data[y + 1];
  233.     dy0 = orig_y[y];
  234.     dy1 = orig_y[y + 1];
  235.     dcr = orig_cr[y / 2];
  236.     dcb = orig_cb[y / 2];
  237.  
  238.     for ( x = 0; x < width; x += 2, dy0 += 2, dy1 += 2, dcr++,
  239.                    dcb++, src0 += 6, src1 += 6)
  240.     {
  241.         *dy0 = (mult299[*src0] +
  242.             mult587[src0[1]] +
  243.             mult114[src0[2]]);
  244.  
  245.         *dy1 = (mult299[*src1] +
  246.             mult587[src1[1]] +
  247.             mult114[src1[2]]);
  248.  
  249.         dy0[1] = (mult299[src0[3]] +
  250.               mult587[src0[4]] +
  251.               mult114[src0[5]]);
  252.  
  253.         dy1[1] = (mult299[src1[3]] +
  254.               mult587[src1[4]] +
  255.               mult114[src1[5]]);
  256.  
  257.         *dcb = ((mult16874[*src0] +
  258.              mult33126[src0[1]] +
  259.              mult5[src0[2]] +
  260.              mult16874[*src1] +
  261.              mult33126[src1[1]] +
  262.              mult5[src1[2]] +
  263.              mult16874[src0[3]] +
  264.              mult33126[src0[4]] +
  265.              mult5[src0[5]] +
  266.              mult16874[src1[3]] +
  267.              mult33126[src1[4]] +
  268.              mult5[src1[5]]) / cdivisor) + 128;
  269.  
  270.         *dcr = ((mult5[*src0] +
  271.              mult41869[src0[1]] +
  272.              mult08131[src0[2]] +
  273.              mult5[*src1] +
  274.              mult41869[src1[1]] +
  275.              mult08131[src1[2]] +
  276.              mult5[src0[3]] +
  277.              mult41869[src0[4]] +
  278.              mult08131[src0[5]] +
  279.              mult5[src1[3]] +
  280.              mult41869[src1[4]] +
  281.              mult08131[src1[5]]) / cdivisor) + 128;
  282.     }
  283.     }
  284. }
  285.  
  286.  
  287. static void WriteYUV(FILE *fpointer)
  288. {
  289.     register int y;
  290.  
  291.     for (y = 0; y < height; y++)                        /* Y */
  292.         fwrite(orig_y[y], 1, width, fpointer);
  293.  
  294.     for (y = 0; y < height / 2; y++)                    /* U */
  295.         fwrite(orig_cb[y], 1, width / 2, fpointer);
  296.  
  297.     for (y = 0; y < height / 2; y++)                    /* V */
  298.         fwrite(orig_cr[y], 1, width / 2, fpointer);
  299. }
  300.