1b3dfa806Smrg/*
2b3dfa806Smrg * PPM file output
3b3dfa806Smrg * Brian Paul
4b3dfa806Smrg * 8 Dec 2008
5b3dfa806Smrg */
6b3dfa806Smrg
7b3dfa806Smrg#include <assert.h>
8b3dfa806Smrg#include <stdio.h>
9b3dfa806Smrg#include <stdlib.h>
10b3dfa806Smrg#include "glutint.h"
11b3dfa806Smrg
12b3dfa806Smrg
13b3dfa806Smrgstatic void
14b3dfa806Smrgwrite_ppm_file(const char *filename, const GLubyte *buffer,
15b3dfa806Smrg               int width, int height)
16b3dfa806Smrg{
17b3dfa806Smrg   const int binary = 1;
18b3dfa806Smrg   FILE *f = fopen( filename, "w" );
19b3dfa806Smrg   if (f) {
20b3dfa806Smrg      const GLubyte *ptr = buffer;
21b3dfa806Smrg      int i, x, y;
22b3dfa806Smrg      if (binary) {
23b3dfa806Smrg         fprintf(f,"P6\n");
24b3dfa806Smrg         fprintf(f,"# ppm-file created by GLUT\n");
25b3dfa806Smrg         fprintf(f,"%i %i\n", width, height);
26b3dfa806Smrg         fprintf(f,"255\n");
27b3dfa806Smrg         fclose(f);
28b3dfa806Smrg         f = fopen( filename, "ab" );  /* reopen in binary append mode */
29b3dfa806Smrg         for (y = height - 1; y >= 0; y--) {
30b3dfa806Smrg            for (x = 0; x < width; x++) {
31b3dfa806Smrg               i = (y * width + x) * 4;
32b3dfa806Smrg               fputc(ptr[i], f);   /* write red */
33b3dfa806Smrg               fputc(ptr[i+1], f); /* write green */
34b3dfa806Smrg               fputc(ptr[i+2], f); /* write blue */
35b3dfa806Smrg            }
36b3dfa806Smrg         }
37b3dfa806Smrg      }
38b3dfa806Smrg      else {
39b3dfa806Smrg         /*ASCII*/
40b3dfa806Smrg         int counter = 0;
41b3dfa806Smrg         fprintf(f,"P3\n");
42b3dfa806Smrg         fprintf(f,"# ascii ppm file created by GLUT\n");
43b3dfa806Smrg         fprintf(f,"%i %i\n", width, height);
44b3dfa806Smrg         fprintf(f,"255\n");
45b3dfa806Smrg         for (y = height - 1; y >= 0; y--) {
46b3dfa806Smrg            for (x = 0; x < width; x++) {
47b3dfa806Smrg               i = (y * width + x) * 4;
48b3dfa806Smrg               fprintf(f, " %3d %3d %3d", ptr[i], ptr[i+1], ptr[i+2]);
49b3dfa806Smrg               counter++;
50b3dfa806Smrg               if (counter % 5 == 0)
51b3dfa806Smrg                  fprintf(f, "\n");
52b3dfa806Smrg            }
53b3dfa806Smrg         }
54b3dfa806Smrg      }
55b3dfa806Smrg      fclose(f);
56b3dfa806Smrg   }
57b3dfa806Smrg}
58b3dfa806Smrg
59b3dfa806Smrg
60b3dfa806Smrg/**
61b3dfa806Smrg * Called from SwapBuffers if the GLUT_PPM_FILE env var is set.
62b3dfa806Smrg */
63b3dfa806Smrgvoid __glutWritePPMFile(void)
64b3dfa806Smrg{
65b3dfa806Smrg   int w = glutGet(GLUT_WINDOW_WIDTH);
66b3dfa806Smrg   int h = glutGet(GLUT_WINDOW_HEIGHT);
67b3dfa806Smrg   GLubyte *buf;
68b3dfa806Smrg
69b3dfa806Smrg   assert(__glutPPMFile);
70b3dfa806Smrg
71b3dfa806Smrg   buf = (GLubyte *) malloc(w * h * 4);
72b3dfa806Smrg   if (buf) {
73b3dfa806Smrg      /* XXX save/restore pixel packing */
74b3dfa806Smrg      glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buf);
75b3dfa806Smrg      write_ppm_file(__glutPPMFile, buf, w, h);
76b3dfa806Smrg      free(buf);
77b3dfa806Smrg   }
78b3dfa806Smrg
79b3dfa806Smrg   __glutPPMFile = NULL; /* only write one file */
80b3dfa806Smrg}
81