/*
* Vis5D system for visualizing five dimensional gridded data sets.
* Copyright (C) 1990 - 2000 Bill Hibbard, Johan Kellum, Brian Paul,
* Dave Santek, and Andre Battaiola.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* As a special exception to the terms of the GNU General Public
* License, you are permitted to link Vis5D with (and distribute the
* resulting source and executables) the LUI library (copyright by
* Stellar Computer Inc. and licensed for distribution with Vis5D),
* the McIDAS library, and/or the NetCDF library, where those
* libraries are governed by the terms of their own licenses.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "../config.h"
#if defined(HAVE_OPENGL) || defined(HAVE_SGI_GL)
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "api.h"
#include "globals.h"
#include "graphics.h"
#include "gl_to_ppm.h"
#if HAVE_OPENGL
# include <GL/gl.h>
# include <GL/glu.h>
# include <GL/glx.h>
#elif HAVE_SGI_GL
# include <gl/gl.h>
#endif
static unsigned char *dataR;
static unsigned char *dataG;
static unsigned char *dataB;
static int current_x_offset;
static int current_y_offset;
static int big_x;
static int big_y;
static FILE *f;
static int write_ppm_val( int number )
{
int val, valer;
if (number > 999){
valer = number / 1000;
number -= valer*1000;
val = valer + '0';
if (fputc(val, f)==EOF){
printf("Error: could not write to output file?\n");
exit(0);
}
valer = number / 100;
number -= valer*100;
val = valer + '0';
if (fputc(val, f)==EOF){
printf("Error: could not write to output file?\n");
exit(0);
}
valer = number / 10;
number -= valer*10;
val = valer + '0';
if (fputc(val, f)==EOF){
printf("Error: could not write to output file?\n");
exit(0);
}
val = number + '0';
if (fputc(val, f)==EOF){
printf("Error: could not write to output file?\n");
exit(0);
}
return 1;
}
if (number > 99){
valer = number / 100;
number -= valer*100;
val = valer + '0';
if (fputc(val, f)==EOF){
printf("Error: could not write to output file?\n");
exit(0);
}
valer = number / 10;
number -= valer*10;
val = valer + '0';
if (fputc(val, f)==EOF){
printf("Error: could not write to output file?\n");
exit(0);
}
val = number + '0';
if (fputc(val, f)==EOF){
printf("Error: could not write to output file?\n");
exit(0);
}
return 1;
}
else if (number > 9){
valer = number / 10;
number -= valer*10;
val = valer + '0';
if (fputc(val, f)==EOF){
printf("Error: could not write to output file?\n");
exit(0);
}
val = number + '0';
if (fputc(val, f)==EOF){
printf("Error: could not write to output file?\n");
exit(0);
}
return 1;
}
else if (number > -1){
val = number + '0';
if (fputc(val, f)==EOF){
printf("Error: could not write to output file?\n");
exit(0);
}
return 1;
}
else{
printf("Error: trying to write a negative number to a ppm file?\n");
exit(0);
}
}
static void free_pixel_data( void )
{
free(dataR);
free(dataG);
free(dataB);
}
int open_ppm_file( char *filename, int x, int y)
{
/**************************/
/* alloc the pixel memory */
/**************************/
dataR = (unsigned char *) malloc(x*y*sizeof(char));
if (!dataR){
printf("Could not allocate memory to save ppm file\n");
return 0;
}
dataG = (unsigned char *) malloc(x*y*sizeof(char));
if (!dataG){
printf("Could not allocate memory to save ppm file\n");
free(dataR);
return 0;
}
dataB = (unsigned char *) malloc(x*y*sizeof(char));
if (!dataB){
printf("Could not allocate memory to save ppm file\n");
free(dataR);
free(dataG);
return 0;
}
/****************************/
/*open the file for writing */
/****************************/
f = fopen( filename, "w");
if (!f){
printf("Could not open %s for writing\n", filename);
return 0;
}
fseek(f, 0, SEEK_SET);
/********************************/
/* write out simple header info */
/********************************/
if (fputc('P', f)==EOF){
printf("Could not write to output file %s\n", filename);
return 0;
}
if (fputc('6', f)==EOF){
printf("Could not write to output file %s\n", filename);
return 0;
}
if (fputc('\n', f)==EOF){
printf("Could not write to output file %s\n", filename);
return 0;
}
if (!write_ppm_val( x)){
printf("Could not write to output file %s\n", filename);
return 0;
}
if (fputc(' ', f)==EOF){
printf("Could not write to output file %s\n", filename);
return 0;
}
if (!write_ppm_val( y)){
printf("Could not write to output file %s\n", filename);
return 0;
}
if (fputc('\n', f)==EOF){
printf("Could not write to output file %s\n", filename);
return 0;
}
if (!write_ppm_val( 255)){
printf("Could not write to output file %s\n", filename);
return 0;
}
if (fputc('\n', f)==EOF){
printf("Could not write to output file %s\n", filename);
return 0;
}
/********************/
/* init some values */
/********************/
current_x_offset = 0;
current_y_offset = 0;
big_x = x;
big_y = y;
return 1;
}
int add_display_to_ppm_file(Display_Context dtx, int position)
{
unsigned char *tempdataR;
unsigned char *tempdataG;
unsigned char *tempdataB;
int x, y, xpos, ypos, p, q;
int bx, by;
set_current_window( dtx );
glPixelStorei(GL_PACK_ALIGNMENT, 1);
check_gl_error( "add_display_to_ppm_file (glPixelStore)" );
/******************************************************/
/*alloc the memory to retrieve data from frame buffer */
/******************************************************/
tempdataR = (unsigned char *) malloc(dtx->WinWidth * dtx->WinHeight*sizeof(unsigned char));
if (!tempdataR){
printf("Could not allocate enough memory to create ppm file\n");
free_pixel_data();
return 0;
}
tempdataG = (unsigned char *) malloc(dtx->WinWidth * dtx->WinHeight*sizeof(unsigned char));
if (!tempdataG){
printf("Could not allocate enough memory to create ppm file\n");
free_pixel_data();
free(tempdataR);
return 0;
}
tempdataB = (unsigned char *) malloc(dtx->WinWidth * dtx->WinHeight*sizeof(unsigned char));
if (!tempdataB){
printf("Could not allocate enough memory to create ppm file\n");
free_pixel_data();
free(tempdataR);
free(tempdataG);
return 0;
}
glReadPixels( 0, 0, dtx->WinWidth, dtx->WinHeight, GL_RED, GL_UNSIGNED_BYTE, tempdataR);
glReadPixels( 0, 0, dtx->WinWidth, dtx->WinHeight, GL_GREEN, GL_UNSIGNED_BYTE, tempdataG);
glReadPixels( 0, 0, dtx->WinWidth, dtx->WinHeight, GL_BLUE, GL_UNSIGNED_BYTE, tempdataB);
check_gl_error( "add_display_to_ppm_file (glReadPixels)" );
/*************************************************/
/* put data from frame buffer data into big data */
/*************************************************/
for (y = 0; y < dtx->WinHeight; y++){
for (x = 0; x < dtx->WinWidth; x++){
/* frame buffer data starts */
/* from lower left corner */
p = ((dtx->WinHeight-1-y)*dtx->WinWidth)+x;
bx = current_x_offset + x;
by = current_y_offset + y;
q = by * big_x + bx;
dataR[q] = tempdataR[p];
dataG[q] = tempdataG[p];
dataB[q] = tempdataB[p];
}
}
/*********************/
/* figure out offset */
/**************************************/
/* assuming raster order for displays!*/
/**************************************/
ypos = position/DisplayCols;
xpos = position - (DisplayCols*ypos);
if (xpos == DisplayCols-1){
current_x_offset = 0;
current_y_offset += dtx->WinHeight;
}
else{
current_x_offset += dtx->WinWidth;
}
free(tempdataR);
free(tempdataG);
free(tempdataB);
tempdataR = NULL;
tempdataG = NULL;
tempdataB = NULL;
return 1;
}
int close_ppm_file(void)
{
int i;
/*****************************************/
/* tranfer data from dataR, dataG, dataB */
/* to file */
/*****************************************/
for (i=0; i<big_x * big_y; i++){
fputc(dataR[i], f);
fputc(dataG[i], f);
fputc(dataB[i], f);
}
fputc(EOF, f);
if (fclose(f)==EOF){
printf("Could not close output ppm file\n");
free_pixel_data();
return 0;
}
printf("Done writing ppm image file.\n");
return 1;
}
#endif /* defined(HAVE_OPENGL) || defined(HAVE_SGI_GL) */
syntax highlighted by Code2HTML, v. 0.9.1