/**************************************************************************** * raw.c * * This module contains the code to read and write the RAW file format * The format is as follows: * * * (header:) * wwww hhhh - Width, Height (16 bits, LSB first) * * (each scanline:) * llll - Line number (16 bits, LSB first) * rr rr rr ... - Red data for line (8 bits per pixel, * left to right, 0-255 (255=bright, 0=dark)) * gg gg gg ... - Green data for line (8 bits per pixel, * left to right, 0-255 (255=bright, 0=dark)) * bb bb bb ... - Blue data for line (8 bits per pixel, * left to right, 0-255 (255=bright, 0=dark)) * * from Persistence of Vision Raytracer * Copyright 1993 Persistence of Vision Team *--------------------------------------------------------------------------- * NOTICE: This source code file is provided so that users may experiment * with enhancements to POV-Ray and to port the software to platforms other * than those supported by the POV-Ray Team. There are strict rules under * which you are permitted to use this file. The rules are in the file * named POVLEGAL.DOC which should be distributed with this file. If * POVLEGAL.DOC is not available or for more info please contact the POV-Ray * Team Coordinator by leaving a message in CompuServe's Graphics Developer's * Forum. The latest version of POV-Ray may be found there as well. * * This program is based on the popular DKB raytracer version 2.12. * DKBTrace was originally written by David K. Buck. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins. ******************************************************************************/ #include "frame.h" #include "povproto.h" struct Raw_File_Handle_Struct { FILE_HANDLE root; FILE *Red_File, *Green_File, *Blue_File; char *Red_Buffer, *Green_Buffer, *Blue_Buffer; int line_number; }; typedef struct Raw_File_Handle_Struct RAW_FILE_HANDLE; FILE_HANDLE *Get_Raw_File_Handle() { RAW_FILE_HANDLE *handle; if ((handle = (RAW_FILE_HANDLE *) malloc(sizeof(RAW_FILE_HANDLE))) == NULL) { fprintf (stderr, "Cannot allocate memory for output file handle\n"); return(NULL); } handle->root.Default_File_Name_p = Default_Raw_File_Name; handle->root.Open_File_p = Open_Raw_File; handle->root.Write_Line_p = Write_Raw_Line; handle->root.Read_Line_p = Read_Raw_Line; handle->root.Close_File_p = Close_Raw_File; return ((FILE_HANDLE *) handle); } char *Default_Raw_File_Name() { return ("data"); } int Open_Raw_File (handle, name, width, height, buffer_size, mode) FILE_HANDLE *handle; char *name; int *width; int *height; /* 16/10/1993 : Marc ABramson: version 1.32, passage du buffer en size_t */ size_t buffer_size; int mode; { RAW_FILE_HANDLE *raw_handle; char file_name[256]; handle->mode = mode; handle->filename = name; raw_handle = (RAW_FILE_HANDLE *) handle; raw_handle->line_number = 0; switch (mode) { case READ_MODE: strcpy (file_name, name); strcat (file_name, RED_RAW_FILE_EXTENSION); if ((raw_handle->Red_File=fopen(file_name,READ_FILE_STRING)) == NULL) return(0); strcpy (file_name, name); strcat (file_name, GREEN_RAW_FILE_EXTENSION); if ((raw_handle->Green_File=fopen(file_name,READ_FILE_STRING))==NULL) return(0); strcpy (file_name, name); strcat (file_name, BLUE_RAW_FILE_EXTENSION); if ((raw_handle->Blue_File=fopen(file_name,READ_FILE_STRING))== NULL) return(0); if (buffer_size != 0) { if ((raw_handle->Red_Buffer = malloc (buffer_size)) == NULL) return(0); setvbuf (raw_handle->Red_File, raw_handle->Red_Buffer, _IOFBF, buffer_size); } if (buffer_size != 0) { if ((raw_handle->Green_Buffer = malloc (buffer_size)) == NULL) return(0); setvbuf (raw_handle->Green_File, raw_handle->Green_Buffer, _IOFBF, buffer_size); } if (buffer_size != 0) { if ((raw_handle->Blue_Buffer = malloc (buffer_size)) == NULL) return(0); setvbuf (raw_handle->Blue_File, raw_handle->Blue_Buffer, _IOFBF, buffer_size); } handle->width = *width; handle->height = *height; handle->buffer_size = buffer_size; break; case WRITE_MODE: strcpy (file_name, name); strcat (file_name, RED_RAW_FILE_EXTENSION); if ((raw_handle->Red_File = fopen (file_name, WRITE_FILE_STRING)) == NULL) return(0); if (buffer_size != 0) { if ((raw_handle->Red_Buffer = malloc (buffer_size)) == NULL) return(0); setvbuf (raw_handle->Red_File, raw_handle->Red_Buffer, _IOFBF, buffer_size); } strcpy (file_name, name); strcat (file_name, GREEN_RAW_FILE_EXTENSION); if ((raw_handle->Green_File = fopen (file_name, WRITE_FILE_STRING)) == NULL) return(0); if (buffer_size != 0) { if ((raw_handle->Green_Buffer = malloc (buffer_size)) == NULL) return(0); setvbuf (raw_handle->Green_File, raw_handle->Green_Buffer, _IOFBF, buffer_size); } strcpy (file_name, name); strcat (file_name, BLUE_RAW_FILE_EXTENSION); if ((raw_handle->Blue_File = fopen (file_name, WRITE_FILE_STRING)) == NULL) return(0); if (buffer_size != 0) { if ((raw_handle->Blue_Buffer = malloc (buffer_size)) == NULL) return(0); setvbuf (raw_handle->Blue_File, raw_handle->Blue_Buffer, _IOFBF, buffer_size); } handle->width = *width; handle->height = *height; handle->buffer_size = buffer_size; break; case APPEND_MODE: strcpy (file_name, name); strcat (file_name, RED_RAW_FILE_EXTENSION); if ((raw_handle->Red_File=fopen(file_name,APPEND_FILE_STRING))==NULL) return(0); if (buffer_size != 0) { if ((raw_handle->Red_Buffer = malloc (buffer_size)) == NULL) return(0); setvbuf (raw_handle->Red_File, raw_handle->Red_Buffer, _IOFBF, buffer_size); } strcpy (file_name, name); strcat (file_name, GREEN_RAW_FILE_EXTENSION); if ((raw_handle->Green_File=fopen(file_name,APPEND_FILE_STRING))==NULL) return(0); if (buffer_size != 0) { if ((raw_handle->Green_Buffer = malloc (buffer_size)) == NULL) return(0); setvbuf (raw_handle->Green_File, raw_handle->Green_Buffer, _IOFBF, buffer_size); } strcpy (file_name, name); strcat (file_name, BLUE_RAW_FILE_EXTENSION); if ((raw_handle->Blue_File=fopen(file_name,APPEND_FILE_STRING))==NULL) return(0); if (buffer_size != 0) { if ((raw_handle->Blue_Buffer = malloc (buffer_size)) == NULL) return(0); setvbuf (raw_handle->Blue_File, raw_handle->Blue_Buffer, _IOFBF, buffer_size); } handle->width = *width; handle->height = *height; handle->buffer_size = buffer_size; break; } return(1); } void Write_Raw_Line (handle, line_data, line_number) FILE_HANDLE *handle; COLOUR *line_data; int line_number; { register int x; RAW_FILE_HANDLE *raw_handle; char file_name[256]; raw_handle = (RAW_FILE_HANDLE *) handle; for (x = 0 ; x < handle->width ; x++) putc((int) floor (line_data[x].Red * 255.0), raw_handle->Red_File); for (x = 0 ; x < handle->width ; x++) putc((int) floor (line_data[x].Green * 255.0), raw_handle->Green_File); for (x = 0 ; x < handle->width ; x++) putc((int) floor (line_data[x].Blue * 255.0), raw_handle->Blue_File); if (handle->buffer_size == 0) { fflush(raw_handle->Red_File); /* close and reopen file for */ strcpy (file_name, handle->filename); strcat (file_name, RED_RAW_FILE_EXTENSION); raw_handle->Red_File = freopen(file_name, APPEND_FILE_STRING, raw_handle->Red_File); /* integrity in case we crash*/ fflush(raw_handle->Green_File); /* close and reopen file for */ strcpy (file_name, handle->filename); strcat (file_name, GREEN_RAW_FILE_EXTENSION); raw_handle->Green_File = freopen(file_name, APPEND_FILE_STRING, raw_handle->Green_File); /* integrity in case we crash*/ fflush(raw_handle->Blue_File); /* close and reopen file for */ strcpy (file_name, handle->filename); strcat (file_name, BLUE_RAW_FILE_EXTENSION); raw_handle->Blue_File = freopen(file_name, APPEND_FILE_STRING, raw_handle->Blue_File); /* integrity in case we crash*/ } } int Read_Raw_Line (handle, line_data, line_number) FILE_HANDLE *handle; COLOUR *line_data; int *line_number; { int data, i; RAW_FILE_HANDLE *raw_handle; raw_handle = (RAW_FILE_HANDLE *) handle; for (i = 0 ; i < handle->width ; i++) { if ((data = getc(raw_handle->Red_File)) == EOF) { if (i == 0) return(0); else return(-1); } line_data[i].Red = (DBL) data / 255.0; } for (i = 0 ; i < handle->width ; i++) { if ((data = getc(raw_handle->Green_File)) == EOF) return(-1); line_data[i].Green = (DBL) data / 255.0; } for (i = 0 ; i < handle->width ; i++) { if ((data = getc(raw_handle->Blue_File)) == EOF) return(-1); line_data[i].Blue = (DBL) data / 255.0; } *line_number = raw_handle->line_number++; return (1); } void Close_Raw_File (handle) FILE_HANDLE *handle; { RAW_FILE_HANDLE *raw_handle; raw_handle = (RAW_FILE_HANDLE *) handle; if(raw_handle->Red_File) fclose (raw_handle->Red_File); if(raw_handle->Green_File) fclose (raw_handle->Green_File); if(raw_handle->Blue_File) fclose (raw_handle->Blue_File); if (handle->buffer_size != 0) { free (raw_handle->Red_Buffer); free (raw_handle->Green_Buffer); free (raw_handle->Blue_Buffer); } }