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

  1. /*===========================================================================*
  2.  * blockppmtoyuv.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. /*==============*
  31.  * HEADER FILES *
  32.  *==============*/
  33.  
  34. #include <stdio.h>
  35. #include "ansi.h"
  36.  
  37.  
  38. typedef    unsigned char uint8;
  39. typedef char int8;
  40. typedef int boolean;
  41. #define TRUE 1
  42. #define FALSE 0
  43.  
  44.  
  45. int        height, width;
  46. uint8   **ppm_data;
  47. uint8 **orig_y, **orig_cr, **orig_cb;
  48.  
  49.  
  50. /*===============================*
  51.  * INTERNAL PROCEDURE prototypes *
  52.  *===============================*/
  53.  
  54. static int  ReadNextInteger _ANSI_ARGS_((FILE *fpointer));
  55. static boolean    ReadPPM _ANSI_ARGS_((FILE *fpointer));
  56. static void WriteYUV _ANSI_ARGS_((FILE *fpointer));
  57. static void PPMtoYUV _ANSI_ARGS_((void));
  58.  
  59.  
  60. void    main(int argc, char **argv)
  61. {
  62.     char    *base;
  63.     int    start, end;
  64.     register int index;
  65.     char    command[256];
  66.     FILE    *fpointer;
  67.     char    inName[256], outName[256];
  68.     int        skip;
  69.  
  70.     if ( argc != 5 )
  71.     {
  72.     fprintf(stderr, "Usage:  %s base start end skip\n\n", argv[0]);
  73.     fprintf(stderr, "Will ppmtoyuv all baseN where N runs from start ");
  74.     fprintf(stderr, "to end, skipping by skip,\n");
  75.     fprintf(stderr, "and deletes the original files, adding .yuv as suffix\n");
  76.     exit(1);
  77.     }
  78.  
  79.     base = argv[1];
  80.     start = atoi(argv[2]);
  81.     end = atoi(argv[3]);
  82.     skip = atoi(argv[4]);
  83.     
  84.     for ( index = start; index <= end; index += skip )
  85.     {
  86.     fprintf(stdout, "converting %d\n", index);
  87.  
  88.     sprintf(inName, "%s%d", base, index);
  89.     sprintf(outName, "%s%d.yuv", base, index);
  90.  
  91.     fpointer = fopen(inName, "r");
  92.     if ( ! ReadPPM(fpointer) )
  93.     {
  94.         fprintf(stderr, "Error reading PPM input file!!!\n");
  95.         exit(1);
  96.     }
  97.     fclose(fpointer);
  98.  
  99.     PPMtoYUV();
  100.  
  101.     fpointer = fopen(outName, "w");
  102.     WriteYUV(fpointer);
  103.     fclose(fpointer);
  104.  
  105.     sprintf(command, "rm %s", inName);
  106.     system(command);
  107.     }
  108. }
  109.  
  110.  
  111. static boolean    ReadPPM(FILE *fpointer)
  112. {
  113.     char    input[256];
  114.     uint8   junk[4096];
  115.     register int y;
  116.     int  maxVal;
  117.  
  118.     if ( fread(input, sizeof(char), 2, fpointer) != 2 )
  119.     return FALSE;
  120.  
  121.     if ( strncmp(input, "P6", 2) != 0 )        /* magic number */
  122.     return FALSE;
  123.  
  124.     width = ReadNextInteger(fpointer);
  125.     if ( width == -1 )
  126.         return FALSE;
  127.  
  128.     height = ReadNextInteger(fpointer);
  129.     if ( height == -1 )
  130.     return FALSE;
  131.  
  132.     maxVal = ReadNextInteger(fpointer);
  133.     if ( maxVal == -1 )
  134.     return FALSE;
  135.  
  136.     if ( maxVal != 255 )
  137.     {
  138.     fprintf(stdout, "MAXVAL != 255!!!  Exiting!\n");
  139.     exit(1);
  140.     }
  141.  
  142.     ppm_data = (uint8 **) malloc(sizeof(uint8 *) * height);
  143.  
  144.     for ( y = 0; y < height; y++ )
  145.     {
  146.         ppm_data[y] = (uint8 *) malloc(3*sizeof(uint8) * width);
  147.     }
  148.  
  149.     for ( y = 0; y < height; y++ )
  150.     {
  151.     fread(ppm_data[y], sizeof(char), 3*width, fpointer);
  152.  
  153.     /* read the leftover stuff on the right side */
  154.     fread(junk, sizeof(char), 3*(width-width), fpointer);
  155.     }
  156.  
  157.     return TRUE;
  158. }
  159.  
  160.  
  161. /*=====================*
  162.  * INTERNAL PROCEDURES *
  163.  *=====================*/
  164.  
  165. static int    ReadNextInteger(FILE *fpointer)
  166. {
  167.     char    input[256];
  168.     int        index;
  169.  
  170.     /* skip whitespace */
  171.     while ( fgets(input, 2, fpointer) != NULL )
  172.     {
  173.     if ( isspace(input[0]) )
  174.         continue;
  175.  
  176.     /* read rest of integer */
  177.     index = 1;
  178.     while ( fgets(&input[index], 2, fpointer) != NULL )
  179.     {
  180.         if ( isspace(input[index]) )
  181.         break;
  182.         index++;
  183.     }
  184.     input[index] = '\0';
  185.  
  186.     return atoi(input);
  187.     }
  188.  
  189.     return -1;        /* end of file reached */
  190. }
  191.  
  192.  
  193.  
  194. /*===========================================================================*
  195.  *
  196.  * PPMtoYUV
  197.  *
  198.  *    convert PPM data into YUV data
  199.  *    assumes that ydivisor = 1
  200.  *
  201.  * RETURNS:    nothing
  202.  *
  203.  * SIDE EFFECTS:    none
  204.  *
  205.  *===========================================================================*/
  206. void PPMtoYUV()
  207. {
  208.     register int x, y;
  209.     register uint8 *dy0, *dy1;
  210.     register uint8 *dcr, *dcb;
  211.     register uint8 *src0, *src1;
  212.     register int cdivisor;
  213.     static boolean  first = TRUE;
  214.     static float  mult299[1024], mult587[1024], mult114[1024];
  215.     static float  mult16874[1024], mult33126[1024], mult5[1024];
  216.     static float mult41869[1024], mult08131[1024];
  217.  
  218.     if ( first )
  219.     {
  220.         register int index;
  221.     register int maxValue;
  222.  
  223.     maxValue = 255;
  224.  
  225.         for ( index = 0; index <= maxValue; index++ )
  226.     {
  227.         mult299[index] = index*0.29900;
  228.         mult587[index] = index*0.58700;
  229.         mult114[index] = index*0.11400;
  230.         mult16874[index] = -0.16874*index;
  231.         mult33126[index] = -0.33126*index;
  232.         mult5[index] = index*0.50000;
  233.         mult41869[index] = -0.41869*index;
  234.         mult08131[index] = -0.08131*index;
  235.     }
  236.     
  237.     first = FALSE;
  238.     }
  239.  
  240.     orig_y = (uint8 **) malloc(sizeof(uint8 *) * height);
  241.     for (y = 0; y < height; y++) {
  242.         orig_y[y] = (uint8 *) malloc(sizeof(uint8) * width);
  243.     }
  244.  
  245.     orig_cr = (uint8 **) malloc(sizeof(int8 *) * height / 2);
  246.     for (y = 0; y < height / 2; y++) {
  247.         orig_cr[y] = (uint8 *) malloc(sizeof(int8) * width / 2);
  248.     }
  249.  
  250.     orig_cb = (uint8 **) malloc(sizeof(int8 *) * height / 2);
  251.     for (y = 0; y < height / 2; y++) {
  252.         orig_cb[y] = (uint8 *) malloc(sizeof(int8) * width / 2);
  253.     }
  254.  
  255.     /* assume ydivisor = 1, so cdivisor = 4 */
  256.     cdivisor = 4;
  257.  
  258.     for (y = 0; y < height; y += 2)
  259.     {
  260.     src0 = ppm_data[y];
  261.     src1 = ppm_data[y + 1];
  262.     dy0 = orig_y[y];
  263.     dy1 = orig_y[y + 1];
  264.     dcr = orig_cr[y / 2];
  265.     dcb = orig_cb[y / 2];
  266.  
  267.     for ( x = 0; x < width; x += 2, dy0 += 2, dy1 += 2, dcr++,
  268.                    dcb++, src0 += 6, src1 += 6)
  269.     {
  270.         *dy0 = (mult299[*src0] +
  271.             mult587[src0[1]] +
  272.             mult114[src0[2]]);
  273.  
  274.         *dy1 = (mult299[*src1] +
  275.             mult587[src1[1]] +
  276.             mult114[src1[2]]);
  277.  
  278.         dy0[1] = (mult299[src0[3]] +
  279.               mult587[src0[4]] +
  280.               mult114[src0[5]]);
  281.  
  282.         dy1[1] = (mult299[src1[3]] +
  283.               mult587[src1[4]] +
  284.               mult114[src1[5]]);
  285.  
  286.         *dcb = ((mult16874[*src0] +
  287.              mult33126[src0[1]] +
  288.              mult5[src0[2]] +
  289.              mult16874[*src1] +
  290.              mult33126[src1[1]] +
  291.              mult5[src1[2]] +
  292.              mult16874[src0[3]] +
  293.              mult33126[src0[4]] +
  294.              mult5[src0[5]] +
  295.              mult16874[src1[3]] +
  296.              mult33126[src1[4]] +
  297.              mult5[src1[5]]) / cdivisor) + 128;
  298.  
  299.         *dcr = ((mult5[*src0] +
  300.              mult41869[src0[1]] +
  301.              mult08131[src0[2]] +
  302.              mult5[*src1] +
  303.              mult41869[src1[1]] +
  304.              mult08131[src1[2]] +
  305.              mult5[src0[3]] +
  306.              mult41869[src0[4]] +
  307.              mult08131[src0[5]] +
  308.              mult5[src1[3]] +
  309.              mult41869[src1[4]] +
  310.              mult08131[src1[5]]) / cdivisor) + 128;
  311.     }
  312.     }
  313. }
  314.  
  315.  
  316. static void WriteYUV(FILE *fpointer)
  317. {
  318.     register int y;
  319.  
  320.     for (y = 0; y < height; y++)                        /* Y */
  321.         fwrite(orig_y[y], 1, width, fpointer);
  322.  
  323.     for (y = 0; y < height / 2; y++)                    /* U */
  324.         fwrite(orig_cb[y], 1, width / 2, fpointer);
  325.  
  326.     for (y = 0; y < height / 2; y++)                    /* V */
  327.         fwrite(orig_cr[y], 1, width / 2, fpointer);
  328. }
  329.