Juan Blasco Cabot (juan++at++glup.irobot.uv.es)
Wed, 26 May 1999 08:26:07 +0200
Here you are a very simple class in standard C++ which enables you to
load and write any RGB / RGBA image file.
I'm sorry it's in spanish, but you seem to understand it.
-----------------------------------------------------------------------
> List Archives, FAQ, FTP: http://www.sgi.com/software/performer/
> Submissions: info-performer++at++sgi.com
> Admin. requests: info-performer-request++at++sgi.com
--
------------------------------------------------------------ Juan Blasco Cabot mailto: juan++at++glup.irobot.uv.es LISITT (ARTEC) Phone: +34 6 364 2253 Dept. Electr. & Informatics Addr: Poligono de la Coma s/n University of Valencia Valencia (SPAIN)
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h>
#define TAM_NOMBRES 256 #define TAM_MAX_BUFFER 32768
// RGB file header // Estructura con la informacion de cabecera de la imagen (FORMATO RGB) //
typedef struct cabecera{ short MAGIC; // Magic de iris. char STORAGE; // Formato de almacenamiento char BPC; // bytes por pixel canal unsigned short DIMENSION; // Numero de dimensiones unsigned short XSIZE; // Tamanyo X en pixels unsigned short YSIZE; // Tamanyo Y en pixels unsigned short ZSIZE; // Tamanyo Z (canales) long PIXMIN; // Max valor de pixel long PIXMAX; // Max valor de pixel char DUMMY[4]; // Pasteta char IMAGENAME[80]; // Nombre de la imagen long COLORMAP; // ID del mapa de color. char DUMMY2[404]; // Pasteta }cabecera, *ptrcab;
// // Funciones de lectura-escritura de diversos tipos a fichero //
// Funciones de escritura de valores en fichero
void putbyte(FILE *outf,unsigned char val) { unsigned char buf[1]; buf[0] = val; fwrite(buf,1,1,outf); } void putshort(FILE *outf,unsigned short val) { unsigned char buf[2]; buf[0] = (val>>8); buf[1] = (val>>0); fwrite(buf,2,1,outf); } static int putlong(FILE *outf,unsigned long val) { unsigned char buf[4]; buf[0] = (val>>24); buf[1] = (val>>16); buf[2] = (val>>8); buf[3] = (val>>0); return fwrite(buf,4,1,outf); } // Funciones de lectura de valores de fichero
unsigned char getbyte(FILE *inf) { unsigned char buf[1]; fread(buf, 1, 1, inf); return (buf[0]); }
unsigned short getshort(FILE *inf) { unsigned char buf[2]; fread(buf,2,1,inf); return(buf[0]<<8)+(buf[1]<<0); } static long getlong(FILE *inf) { unsigned char buf[4]; fread(buf,4,1,inf); return (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+(buf[3]<<0); } void escribir_imagen(ptrcab cab, char*imagen, char*nombre) { FILE *of; char iname[80]; unsigned char outbuf[512]; int i, cont, x, y; char *nomfich; // Anyadimos la extension .rgb o .rgba al nombre del fichero nomfich=(char*)malloc(sizeof(char)*TAM_NOMBRES); strcpy(nomfich, nombre); if(cab->ZSIZE==4) strcat(nomfich, ".rgba"); else strcat(nomfich, ".rgb"); // Creamos el fichero of = fopen(nomfich,"w"); if(!of) { fprintf(stderr,"No se ha podido crear el fichero de salida %s\n", nomfich); exit(1); } // Escribimos la cabecera putshort(of,474); putbyte(of,0); putbyte(of,cab->BPC); putshort(of,cab->DIMENSION); putshort(of,cab->XSIZE); putshort(of,cab->YSIZE); putshort(of,cab->ZSIZE); putlong(of,cab->PIXMIN); putlong(of,cab->PIXMAX); for(i=0; i<4; i++) putbyte(of,0); strcpy(iname,"No Name"); fwrite(iname,80,1,of); putlong(of,cab->COLORMAP); for(i=0; i<404; i++) putbyte(of,0);
// Escribimos los datos(pixels) de la imagen cont=0; for(i=0;i<cab->ZSIZE;i++) for(y=0; y<cab->YSIZE; y++) { for(x=0; x<cab->XSIZE; x++) outbuf[x] = imagen[cont++]; fwrite(outbuf,cab->XSIZE,1,of); } fclose(of); // Libera la memoria del string del nombre de fichero. free(nomfich); }
void copia_cabecera(ptrcab cap, ptrcab cab) { int i; cap->MAGIC =cab->MAGIC; cap->STORAGE =cab->STORAGE; cap->BPC =cab->BPC; cap->DIMENSION =cab->DIMENSION; cap->XSIZE =cab->XSIZE; cap->YSIZE =cab->YSIZE; cap->ZSIZE =cab->ZSIZE; cap->PIXMIN =cab->PIXMIN; cap->PIXMAX =cab->PIXMAX; for(i=0; i<4; i++) cap->DUMMY[i]=cab->DUMMY[i]; for(i=0; i<80; i++) cap->IMAGENAME[i]=cab->IMAGENAME[i]; cap->COLORMAP=cab->COLORMAP; for(i=0; i<404; i++) cap->DUMMY2[i]=cab->DUMMY2[i]; } // // // CLASE IMAGEN (CImagen) // //
class CImagen{ public: CImagen(); ~CImagen(); void abrir(char*nombre); // open void escribir(char*nombre); // write private:
// Datos propios de la imagen FILE *f; // File. ptrcab cab; // Header. char *img; // Image data (RGBA). int abrir_fich(char*nombre); // opens file void leer_cabecera(); // reads file header void leer_datos(); // reads data void escribir_cabecera(); // writes header unsigned char comprobar_cabecera(); // Checks header }; CImagen::CImagen() { cab=new cabecera; }
CImagen::~CImagen() { delete(cab); delete(img); }
/*********************************************************************************** * Funcion void CImagen::abrir(char *nombre) * * Parametros: char * nombre: Nombre del fichero que contiene la imagen * * Retorno: int: Indica si el fichero se ha abierto correctamente (0). * * Funcionamiento: Abre el fichero que contiene la imagen completa para lectura. * Si no lo consigue, saca un mensaje de error y finaliza el programa. * ***********************************************************************************/
int CImagen::abrir_fich(char*nombre) { f = fopen(nombre,"rb"); if(!f) { fprintf(stderr,"sgiimage: Error al leer el fichero %s.\n", nombre); exit(1); } return(0); }
/*********************************************************************************** * Funcion void CImagen::leer_cabecera() * * Parametros: No * * Retorno: No. * * Funcionamiento: Carga en memoria los valores de la cabecera contenida en fichero* ***********************************************************************************/ void CImagen::leer_cabecera() { int i; cab->MAGIC=getshort(f); cab->STORAGE=getbyte(f); cab->BPC=getbyte(f); cab->DIMENSION=getshort(f); cab->XSIZE=getshort(f); cab->YSIZE=getshort(f); cab->ZSIZE=getshort(f); cab->PIXMIN=getlong(f); cab->PIXMAX=getlong(f); for(i=0; i<4; i++) cab->DUMMY[i]=getbyte(f); for(i=0; i<80; i++) cab->IMAGENAME[i]=getbyte(f); cab->COLORMAP=getlong(f); for(i=0; i<404; i++) cab->DUMMY2[i]=getbyte(f); }
/*********************************************************************************** * Funcion void CImagen::escribir_cabecera() * * Parametros: No * * Retorno: No. * * Funcionamiento: Imprime en pantalla los valores de los campos de la cabecera * ***********************************************************************************/ void CImagen::escribir_cabecera() { printf("\nMAGIC: %i", cab->MAGIC); printf("\nSTORAGE: %i", cab->STORAGE); printf("\nBPC: %i", cab->BPC); printf("\nDIMENSION: %i", cab->DIMENSION); printf("\nXSIZE: %i", cab->XSIZE); printf("\nYSIZE: %i", cab->YSIZE); printf("\nZSIZE: %i", cab->ZSIZE); printf("\nPIXMIN: %i", cab->PIXMIN); printf("\nPIXMAX: %i", cab->PIXMAX); printf("\nDUMMY: %s", cab->DUMMY); printf("\nIMAGENAME: %s", cab->IMAGENAME); printf("\nCOLORMAP: %i", cab->COLORMAP); printf("\nDUMMY2: %s", cab->DUMMY2); printf("\n"); }
/*********************************************************************************** * Funcion unsigned char CImagen::comprobar_cabecera() * * Parametros: No * * Retorno: unsigned char result: Indica si la imagen es valida(1) o no(0). * * Funcionamiento: Consulta los distintos campos de la cabecera, comprobando que * * sus valores coinciden con los necesarios para el programa. * ***********************************************************************************/ unsigned char CImagen::comprobar_cabecera() { unsigned char result=1; // Suponemos que es valida if(cab->MAGIC!=474) // Y vamos comprobando condiciones de validez result=0; // En cuanto no se cumpla una, no es valida if (cab->STORAGE!=0) result=0; if(result) printf("La imagen es valida\n");
// XXX:NOTA: Esto se ha de ampliar mucho!!!!!!!!!!!!!!!!!!!!!!!!!!!!
return (result); } /*********************************************************************************** * Funcion void CImagen::leer_datos(void) * * Parametros: No * * Retorno: No. * * Funcionamiento: Almacena en memoria la imagen contenida en el fichero. * ***********************************************************************************/ void CImagen::leer_datos() { int tamx, tamy; int x, y, i, j; // Reservamos el espacio necesario en funcion del tamanyo */ tamx=cab->XSIZE; tamy=cab->YSIZE; img=(char*)malloc(sizeof(char)*(tamx*tamy)*cab->ZSIZE); // Leemos byte a byte for(j=0;j<cab->ZSIZE;j++) { i=j*(tamx*tamy); for(y=0;y<tamy;y++) for(x=0;x<tamx; x++) img[i++]=getbyte(f); } }
/*********************************************************************************** * Funcion void CImagen::abrir(char *nombre) * * Parametros: char * nombre: Nombre del fichero que contiene la imagen * * Retorno: No. * * Funcionamiento: Abre el fichero que contiene la imagen completa y la almacena * * en memoria. * ***********************************************************************************/
void CImagen::abrir(char *nombre) { abrir_fich(nombre); leer_cabecera(); if (comprobar_cabecera()) leer_datos(); else { printf("La imagen no es valida. Detalles:\n"); escribir_cabecera(); exit(-1); } } /*********************************************************************************** * Funcion void CImagen::escribir(char *nombre) * * Parametros: char * nombre: Nombre del fichero en el que se escribira la imagen * * Retorno: No. * * Funcionamiento: Almacena la imagen en un fichero con formato RGB(A) * ***********************************************************************************/
void CImagen::escribir(char*nombre) { FILE *of; // Fichero de salida char iname[80]; // Auxiliar para la cabecera unsigned char *outbuf; // Buffer de escritura. int i, cont, x, y; // Indices. char *nomfich; // Nombre definitivo del fichero. // Reservamos memoria para el buffer de escritura outbuf=(unsigned char*)malloc(sizeof(unsigned char)*TAM_MAX_BUFFER); // Anyadimos la extension .rgb o .rgba al nombre del fichero nomfich=(char*)malloc(sizeof(char)*TAM_NOMBRES); strcpy(nomfich, nombre); if(cab->ZSIZE==4) strcat(nomfich, ".rgba"); else strcat(nomfich, ".rgb"); // Creamos el fichero of = fopen(nomfich,"w"); if(!of) { fprintf(stderr,"No se ha podido crear el fichero de salida %s\n", nomfich); exit(1); } // Escribimos la cabecera putshort(of,474); putbyte(of,0); putbyte(of,cab->BPC); putshort(of,cab->DIMENSION); putshort(of,cab->XSIZE); putshort(of,cab->YSIZE); putshort(of,cab->ZSIZE); putlong(of,cab->PIXMIN); putlong(of,cab->PIXMAX); for(i=0; i<4; i++) putbyte(of,0); strcpy(iname,"No Name"); fwrite(iname,80,1,of); putlong(of,cab->COLORMAP); for(i=0; i<404; i++) putbyte(of,0); // Escribimos los datos(pixels) de la imagen cont=0; for(i=0;i<cab->ZSIZE;i++) for(y=0; y<cab->YSIZE; y++) { for(x=0; x<cab->XSIZE; x++) outbuf[x] = img[cont++]; fwrite(outbuf,cab->XSIZE,1,of); } fclose(of); // Libera la memoria del string del nombre de fichero. free(nomfich); free(outbuf); }
This archive was generated by hypermail 2.0b2 on Tue May 25 1999 - 23:53:46 PDT