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