1 /*
2 Copyright (c) 2005-2021 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 /*
18 The original source for this example is
19 Copyright (c) 1994-2008 John E. Stone
20 All rights reserved.
21
22 Redistribution and use in source and binary forms, with or without
23 modification, are permitted provided that the following conditions
24 are met:
25 1. Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 2. Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in the
29 documentation and/or other materials provided with the distribution.
30 3. The name of the author may not be used to endorse or promote products
31 derived from this software without specific prior written permission.
32
33 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
34 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
37 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 SUCH DAMAGE.
44 */
45
46 /*
47 * tgafile.cpp - This file contains the code to write 24 bit targa files...
48 */
49
50 #include "machine.hpp"
51 #include "types.hpp"
52 #include "util.hpp"
53 #include "ui.hpp"
54 #include "imageio.hpp"
55 #include "tgafile.hpp"
56
createtgafile(char * name,unsigned short width,unsigned short height)57 void createtgafile(char *name, unsigned short width, unsigned short height) {
58 int filesize;
59 FILE *ofp;
60
61 filesize = 3 * width * height + 18 - 10;
62
63 if (name == nullptr)
64 std::exit(-1);
65 else {
66 ofp = fopen(name, "w+b");
67 if (ofp == nullptr) {
68 char msgtxt[2048];
69 sprintf(msgtxt, "Cannot create %s for output!", name);
70 rt_ui_message(MSG_ERR, msgtxt);
71 rt_ui_message(MSG_ABORT, "Rendering Aborted.");
72 std::exit(-1);
73 }
74
75 fputc(0, ofp); /* IdLength */
76 fputc(0, ofp); /* ColorMapType */
77 fputc(2, ofp); /* ImageTypeCode */
78 fputc(0, ofp); /* ColorMapOrigin, low byte */
79 fputc(0, ofp); /* ColorMapOrigin, high byte */
80 fputc(0, ofp); /* ColorMapLength, low byte */
81 fputc(0, ofp); /* ColorMapLength, high byte */
82 fputc(0, ofp); /* ColorMapEntrySize */
83 fputc(0, ofp); /* XOrigin, low byte */
84 fputc(0, ofp); /* XOrigin, high byte */
85 fputc(0, ofp); /* YOrigin, low byte */
86 fputc(0, ofp); /* YOrigin, high byte */
87 fputc((width & 0xff), ofp); /* Width, low byte */
88 fputc(((width >> 8) & 0xff), ofp); /* Width, high byte */
89 fputc((height & 0xff), ofp); /* Height, low byte */
90 fputc(((height >> 8) & 0xff), ofp); /* Height, high byte */
91 fputc(24, ofp); /* ImagePixelSize */
92 fputc(0x20, ofp); /* ImageDescriptorByte 0x20 == flip vertically */
93
94 fseek(ofp, filesize, 0);
95 fprintf(ofp, "9876543210");
96
97 fclose(ofp);
98 }
99 }
100
opentgafile(char * filename)101 void *opentgafile(char *filename) {
102 FILE *ofp;
103
104 ofp = fopen(filename, "r+b");
105 if (ofp == nullptr) {
106 char msgtxt[2048];
107 sprintf(msgtxt, "Cannot open %s for output!", filename);
108 rt_ui_message(MSG_ERR, msgtxt);
109 rt_ui_message(MSG_ABORT, "Rendering Aborted.");
110 std::exit(-1);
111 }
112
113 return ofp;
114 }
115
writetgaregion(void * voidofp,int iwidth,int iheight,int startx,int starty,int stopx,int stopy,char * buffer)116 void writetgaregion(void *voidofp,
117 int iwidth,
118 int iheight,
119 int startx,
120 int starty,
121 int stopx,
122 int stopy,
123 char *buffer) {
124 int y, totalx, totaly;
125 char *bufpos;
126 long filepos;
127 std::size_t numbytes;
128 FILE *ofp = (FILE *)voidofp;
129
130 totalx = stopx - startx + 1;
131 totaly = stopy - starty + 1;
132
133 for (y = 0; y < totaly; y++) {
134 bufpos = buffer + (totalx * 3) * (totaly - y - 1);
135 filepos = 18 + iwidth * 3 * (iheight - starty - totaly + y + 1) + (startx - 1) * 3;
136
137 if (filepos >= 18) {
138 fseek(ofp, filepos, 0);
139 numbytes = fwrite(bufpos, 3, totalx, ofp);
140
141 if (numbytes != totalx) {
142 char msgtxt[256];
143 sprintf(msgtxt, "File write problem, %d bytes written.", (int)numbytes);
144 rt_ui_message(MSG_ERR, msgtxt);
145 }
146 }
147 else {
148 rt_ui_message(MSG_ERR, "writetgaregion: file ptr out of range!!!\n");
149 return; /* don't try to continue */
150 }
151 }
152 }
153
readtga(char * name,int * xres,int * yres,unsigned char ** imgdata)154 int readtga(char *name, int *xres, int *yres, unsigned char **imgdata) {
155 int format, width, height, w1, w2, h1, h2, depth, flags;
156 int imgsize, i, tmp;
157 std::size_t bytesread;
158 FILE *ifp;
159
160 ifp = fopen(name, "r");
161 if (ifp == nullptr) {
162 return IMAGEBADFILE; /* couldn't open the file */
163 }
164
165 /* read the targa header */
166 getc(ifp); /* ID length */
167 getc(ifp); /* colormap type */
168 format = getc(ifp); /* image type */
169 getc(ifp); /* color map origin */
170 getc(ifp); /* color map origin */
171 getc(ifp); /* color map length */
172 getc(ifp); /* color map length */
173 getc(ifp); /* color map entry size */
174 getc(ifp); /* x origin */
175 getc(ifp); /* x origin */
176 getc(ifp); /* y origin */
177 getc(ifp); /* y origin */
178 w1 = getc(ifp); /* width (low) */
179 w2 = getc(ifp); /* width (hi) */
180 h1 = getc(ifp); /* height (low) */
181 h2 = getc(ifp); /* height (hi) */
182 depth = getc(ifp); /* image pixel size */
183 flags = getc(ifp); /* image descriptor byte */
184
185 if ((format != 2) || (depth != 24)) {
186 fclose(ifp);
187 return IMAGEUNSUP; /* unsupported targa format */
188 }
189
190 width = ((w2 << 8) | w1);
191 height = ((h2 << 8) | h1);
192
193 imgsize = 3 * width * height;
194 *imgdata = (unsigned char *)rt_getmem(imgsize);
195 bytesread = fread(*imgdata, 1, imgsize, ifp);
196 fclose(ifp);
197
198 /* flip image vertically */
199 if (flags == 0x20) {
200 int rowsize = 3 * width;
201 unsigned char *copytmp;
202
203 copytmp = (unsigned char *)malloc(rowsize);
204
205 for (i = 0; i < height / 2; i++) {
206 memcpy(copytmp, &((*imgdata)[rowsize * i]), rowsize);
207 memcpy(&(*imgdata)[rowsize * i], &(*imgdata)[rowsize * (height - 1 - i)], rowsize);
208 memcpy(&(*imgdata)[rowsize * (height - 1 - i)], copytmp, rowsize);
209 }
210
211 free(copytmp);
212 }
213
214 /* convert from BGR order to RGB order */
215 for (i = 0; i < imgsize; i += 3) {
216 tmp = (*imgdata)[i]; /* Blue */
217 (*imgdata)[i] = (*imgdata)[i + 2]; /* Red */
218 (*imgdata)[i + 2] = tmp; /* Blue */
219 }
220
221 *xres = width;
222 *yres = height;
223
224 if (bytesread != imgsize)
225 return IMAGEREADERR;
226
227 return IMAGENOERR;
228 }
229