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 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 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 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 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