home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 9
/
CD_ASCQ_09_1193.iso
/
news
/
4441
/
mpegcode
/
misc
/
blockppm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-01
|
8KB
|
329 lines
/*===========================================================================*
* blockppmtoyuv.c *
* *
* program to convert ppm file to yuv file *
* *
*===========================================================================*/
/*
* Copyright (c) 1993 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*==============*
* HEADER FILES *
*==============*/
#include <stdio.h>
#include "ansi.h"
typedef unsigned char uint8;
typedef char int8;
typedef int boolean;
#define TRUE 1
#define FALSE 0
int height, width;
uint8 **ppm_data;
uint8 **orig_y, **orig_cr, **orig_cb;
/*===============================*
* INTERNAL PROCEDURE prototypes *
*===============================*/
static int ReadNextInteger _ANSI_ARGS_((FILE *fpointer));
static boolean ReadPPM _ANSI_ARGS_((FILE *fpointer));
static void WriteYUV _ANSI_ARGS_((FILE *fpointer));
static void PPMtoYUV _ANSI_ARGS_((void));
void main(int argc, char **argv)
{
char *base;
int start, end;
register int index;
char command[256];
FILE *fpointer;
char inName[256], outName[256];
int skip;
if ( argc != 5 )
{
fprintf(stderr, "Usage: %s base start end skip\n\n", argv[0]);
fprintf(stderr, "Will ppmtoyuv all baseN where N runs from start ");
fprintf(stderr, "to end, skipping by skip,\n");
fprintf(stderr, "and deletes the original files, adding .yuv as suffix\n");
exit(1);
}
base = argv[1];
start = atoi(argv[2]);
end = atoi(argv[3]);
skip = atoi(argv[4]);
for ( index = start; index <= end; index += skip )
{
fprintf(stdout, "converting %d\n", index);
sprintf(inName, "%s%d", base, index);
sprintf(outName, "%s%d.yuv", base, index);
fpointer = fopen(inName, "r");
if ( ! ReadPPM(fpointer) )
{
fprintf(stderr, "Error reading PPM input file!!!\n");
exit(1);
}
fclose(fpointer);
PPMtoYUV();
fpointer = fopen(outName, "w");
WriteYUV(fpointer);
fclose(fpointer);
sprintf(command, "rm %s", inName);
system(command);
}
}
static boolean ReadPPM(FILE *fpointer)
{
char input[256];
uint8 junk[4096];
register int y;
int maxVal;
if ( fread(input, sizeof(char), 2, fpointer) != 2 )
return FALSE;
if ( strncmp(input, "P6", 2) != 0 ) /* magic number */
return FALSE;
width = ReadNextInteger(fpointer);
if ( width == -1 )
return FALSE;
height = ReadNextInteger(fpointer);
if ( height == -1 )
return FALSE;
maxVal = ReadNextInteger(fpointer);
if ( maxVal == -1 )
return FALSE;
if ( maxVal != 255 )
{
fprintf(stdout, "MAXVAL != 255!!! Exiting!\n");
exit(1);
}
ppm_data = (uint8 **) malloc(sizeof(uint8 *) * height);
for ( y = 0; y < height; y++ )
{
ppm_data[y] = (uint8 *) malloc(3*sizeof(uint8) * width);
}
for ( y = 0; y < height; y++ )
{
fread(ppm_data[y], sizeof(char), 3*width, fpointer);
/* read the leftover stuff on the right side */
fread(junk, sizeof(char), 3*(width-width), fpointer);
}
return TRUE;
}
/*=====================*
* INTERNAL PROCEDURES *
*=====================*/
static int ReadNextInteger(FILE *fpointer)
{
char input[256];
int index;
/* skip whitespace */
while ( fgets(input, 2, fpointer) != NULL )
{
if ( isspace(input[0]) )
continue;
/* read rest of integer */
index = 1;
while ( fgets(&input[index], 2, fpointer) != NULL )
{
if ( isspace(input[index]) )
break;
index++;
}
input[index] = '\0';
return atoi(input);
}
return -1; /* end of file reached */
}
/*===========================================================================*
*
* PPMtoYUV
*
* convert PPM data into YUV data
* assumes that ydivisor = 1
*
* RETURNS: nothing
*
* SIDE EFFECTS: none
*
*===========================================================================*/
void PPMtoYUV()
{
register int x, y;
register uint8 *dy0, *dy1;
register uint8 *dcr, *dcb;
register uint8 *src0, *src1;
register int cdivisor;
static boolean first = TRUE;
static float mult299[1024], mult587[1024], mult114[1024];
static float mult16874[1024], mult33126[1024], mult5[1024];
static float mult41869[1024], mult08131[1024];
if ( first )
{
register int index;
register int maxValue;
maxValue = 255;
for ( index = 0; index <= maxValue; index++ )
{
mult299[index] = index*0.29900;
mult587[index] = index*0.58700;
mult114[index] = index*0.11400;
mult16874[index] = -0.16874*index;
mult33126[index] = -0.33126*index;
mult5[index] = index*0.50000;
mult41869[index] = -0.41869*index;
mult08131[index] = -0.08131*index;
}
first = FALSE;
}
orig_y = (uint8 **) malloc(sizeof(uint8 *) * height);
for (y = 0; y < height; y++) {
orig_y[y] = (uint8 *) malloc(sizeof(uint8) * width);
}
orig_cr = (uint8 **) malloc(sizeof(int8 *) * height / 2);
for (y = 0; y < height / 2; y++) {
orig_cr[y] = (uint8 *) malloc(sizeof(int8) * width / 2);
}
orig_cb = (uint8 **) malloc(sizeof(int8 *) * height / 2);
for (y = 0; y < height / 2; y++) {
orig_cb[y] = (uint8 *) malloc(sizeof(int8) * width / 2);
}
/* assume ydivisor = 1, so cdivisor = 4 */
cdivisor = 4;
for (y = 0; y < height; y += 2)
{
src0 = ppm_data[y];
src1 = ppm_data[y + 1];
dy0 = orig_y[y];
dy1 = orig_y[y + 1];
dcr = orig_cr[y / 2];
dcb = orig_cb[y / 2];
for ( x = 0; x < width; x += 2, dy0 += 2, dy1 += 2, dcr++,
dcb++, src0 += 6, src1 += 6)
{
*dy0 = (mult299[*src0] +
mult587[src0[1]] +
mult114[src0[2]]);
*dy1 = (mult299[*src1] +
mult587[src1[1]] +
mult114[src1[2]]);
dy0[1] = (mult299[src0[3]] +
mult587[src0[4]] +
mult114[src0[5]]);
dy1[1] = (mult299[src1[3]] +
mult587[src1[4]] +
mult114[src1[5]]);
*dcb = ((mult16874[*src0] +
mult33126[src0[1]] +
mult5[src0[2]] +
mult16874[*src1] +
mult33126[src1[1]] +
mult5[src1[2]] +
mult16874[src0[3]] +
mult33126[src0[4]] +
mult5[src0[5]] +
mult16874[src1[3]] +
mult33126[src1[4]] +
mult5[src1[5]]) / cdivisor) + 128;
*dcr = ((mult5[*src0] +
mult41869[src0[1]] +
mult08131[src0[2]] +
mult5[*src1] +
mult41869[src1[1]] +
mult08131[src1[2]] +
mult5[src0[3]] +
mult41869[src0[4]] +
mult08131[src0[5]] +
mult5[src1[3]] +
mult41869[src1[4]] +
mult08131[src1[5]]) / cdivisor) + 128;
}
}
}
static void WriteYUV(FILE *fpointer)
{
register int y;
for (y = 0; y < height; y++) /* Y */
fwrite(orig_y[y], 1, width, fpointer);
for (y = 0; y < height / 2; y++) /* U */
fwrite(orig_cb[y], 1, width / 2, fpointer);
for (y = 0; y < height / 2; y++) /* V */
fwrite(orig_cr[y], 1, width / 2, fpointer);
}