ImageOutputDev.cpp
1//========================================================================
2//
3// ImageOutputDev.cpp
4//
5// Copyright 1998-2002 Glyph & Cog, LLC
6//
7//========================================================================
8
9#include <aconf.h>
10
11#ifdef USE_GCC_PRAGMAS
12#pragma implementation
13#endif
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <stddef.h>
18#include <ctype.h>
19#include "gmem.h"
20#include "config.h"
21#include "Error.h"
22#include "GfxState.h"
23#include "Object.h"
24#include "Stream.h"
25#include "ImageOutputDev.h"
26
27ImageOutputDev::ImageOutputDev(char *fileRootA, GBool dumpJPEGA) {
28 fileRoot = copyString(fileRootA);
29 fileName = (char *)gmalloc(strlen(fileRoot) + 20);
30 dumpJPEG = dumpJPEGA;
31 imgNum = 0;
32 ok = gTrue;
33}
34
35ImageOutputDev::~ImageOutputDev() {
36 gfree(fileName);
37 gfree(fileRoot);
38}
39
40void ImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
41 int width, int height, GBool invert,
42 GBool inlineImg) {
43 FILE *f;
44 int c;
45 int size, i;
46
47 // dump JPEG file
48 if (dumpJPEG && str->getKind() == strDCT && !inlineImg) {
49
50 // open the image file
51 sprintf(fileName, "%s-%03d.jpg", fileRoot, imgNum);
52 ++imgNum;
53 if (!(f = fopen(fileName, "wb"))) {
54 error(-1, "Couldn't open image file '%s'", fileName);
55 return;
56 }
57
58 // initialize stream
59 str = ((DCTStream *)str)->getRawStream();
60 str->reset();
61
62 // copy the stream
63 while ((c = str->getChar()) != EOF)
64 fputc(c, f);
65
66 str->close();
67 fclose(f);
68
69 // dump PBM file
70 } else {
71
72 // open the image file and write the PBM header
73 sprintf(fileName, "%s-%03d.pbm", fileRoot, imgNum);
74 ++imgNum;
75 if (!(f = fopen(fileName, "wb"))) {
76 error(-1, "Couldn't open image file '%s'", fileName);
77 return;
78 }
79 fprintf(f, "P4\n");
80 fprintf(f, "%d %d\n", width, height);
81
82 // initialize stream
83 str->reset();
84
85 // copy the stream
86 size = height * ((width + 7) / 8);
87 for (i = 0; i < size; ++i) {
88 fputc(str->getChar(), f);
89 }
90
91 str->close();
92 fclose(f);
93 }
94}
95
96void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
97 int width, int height,
98 GfxImageColorMap *colorMap,
99 int *maskColors, GBool inlineImg) {
100 FILE *f;
101 ImageStream *imgStr;
102 Guchar *p;
103 GfxRGB rgb;
104 int x, y;
105 int c;
106 int size, i;
107
108 // dump JPEG file
109 if (dumpJPEG && str->getKind() == strDCT &&
110 colorMap->getNumPixelComps() == 3 &&
111 !inlineImg) {
112
113 // open the image file
114 sprintf(fileName, "%s-%03d.jpg", fileRoot, imgNum);
115 ++imgNum;
116 if (!(f = fopen(fileName, "wb"))) {
117 error(-1, "Couldn't open image file '%s'", fileName);
118 return;
119 }
120
121 // initialize stream
122 str = ((DCTStream *)str)->getRawStream();
123 str->reset();
124
125 // copy the stream
126 while ((c = str->getChar()) != EOF)
127 fputc(c, f);
128
129 str->close();
130 fclose(f);
131
132 // dump PBM file
133 } else if (colorMap->getNumPixelComps() == 1 &&
134 colorMap->getBits() == 1) {
135
136 // open the image file and write the PBM header
137 sprintf(fileName, "%s-%03d.pbm", fileRoot, imgNum);
138 ++imgNum;
139 if (!(f = fopen(fileName, "wb"))) {
140 error(-1, "Couldn't open image file '%s'", fileName);
141 return;
142 }
143 fprintf(f, "P4\n");
144 fprintf(f, "%d %d\n", width, height);
145
146 // initialize stream
147 str->reset();
148
149 // copy the stream
150 size = height * ((width + 7) / 8);
151 for (i = 0; i < size; ++i) {
152 fputc(str->getChar() ^ 0xff, f);
153 }
154
155 str->close();
156 fclose(f);
157
158 // dump PPM file
159 } else {
160
161 // open the image file and write the PPM header
162 sprintf(fileName, "%s-%03d.ppm", fileRoot, imgNum);
163 ++imgNum;
164 if (!(f = fopen(fileName, "wb"))) {
165 error(-1, "Couldn't open image file '%s'", fileName);
166 return;
167 }
168 fprintf(f, "P6\n");
169 fprintf(f, "%d %d\n", width, height);
170 fprintf(f, "255\n");
171
172 // initialize stream
173 imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
174 colorMap->getBits());
175 imgStr->reset();
176
177 // for each line...
178 for (y = 0; y < height; ++y) {
179
180 // write the line
181 p = imgStr->getLine();
182 for (x = 0; x < width; ++x) {
183 colorMap->getRGB(p, &rgb);
184 fputc((int)(rgb.r * 255 + 0.5), f);
185 fputc((int)(rgb.g * 255 + 0.5), f);
186 fputc((int)(rgb.b * 255 + 0.5), f);
187 p += colorMap->getNumPixelComps();
188 }
189 }
190 delete imgStr;
191
192 fclose(f);
193 }
194}