source: mainline/uspace/lib/draw/codec/tga.c@ eec201d

Last change on this file since eec201d was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 6.8 KB
RevLine 
[6d5e378]1/*
2 * Copyright (c) 2011 Martin Decky
3 * Copyright (c) 2011 Petr Koupy
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup draw
31 * @{
32 */
33/**
34 * @file
35 */
36
37#include <stdlib.h>
38#include <byteorder.h>
39#include <align.h>
[3e6a98c5]40#include <stdbool.h>
[6d5e378]41#include <pixconv.h>
42#include "tga.h"
43
44typedef struct {
45 uint8_t id_length;
46 uint8_t cmap_type;
47 uint8_t img_type;
[a35b458]48
[6d5e378]49 uint16_t cmap_first_entry;
50 uint16_t cmap_entries;
51 uint8_t cmap_bpp;
[a35b458]52
[6d5e378]53 uint16_t startx;
54 uint16_t starty;
55 uint16_t width;
56 uint16_t height;
57 uint8_t img_bpp;
58 uint8_t img_descr;
59} __attribute__((packed)) tga_header_t;
60
61typedef enum {
62 CMAP_NOT_PRESENT = 0,
63 CMAP_PRESENT = 1,
64 CMAP_RESERVED_START = 2,
65 CMAP_PRIVATE_START = 128
66} cmap_type_t;
67
68typedef enum {
69 IMG_EMTPY = 0,
70 IMG_CMAP = 1,
71 IMG_BGRA = 2,
72 IMG_GRAY = 3,
73 IMG_CMAP_RLE = 9,
74 IMG_BGRA_RLE = 10,
75 IMG_GRAY_RLE = 11
76} img_type_t;
77
78typedef struct {
79 cmap_type_t cmap_type;
80 img_type_t img_type;
[a35b458]81
[6d5e378]82 uint16_t cmap_first_entry;
83 uint16_t cmap_entries;
84 uint8_t cmap_bpp;
[a35b458]85
[6d5e378]86 uint16_t startx;
87 uint16_t starty;
88 uint16_t width;
89 uint16_t height;
90 uint8_t img_bpp;
91 uint8_t img_alpha_bpp;
92 uint8_t img_alpha_dir;
[a35b458]93
[6d5e378]94 void *id_data;
95 size_t id_length;
[a35b458]96
[6d5e378]97 void *cmap_data;
98 size_t cmap_length;
[a35b458]99
[6d5e378]100 void *img_data;
101 size_t img_length;
102} tga_t;
103
104/** Decode Truevision TGA header
105 *
106 * @param[in] data Memory representation of TGA.
107 * @param[in] size Size of the representation (in bytes).
108 * @param[out] tga Decoded TGA.
109 *
110 * @return True on succesful decoding.
111 * @return False on failure.
[9250517]112 *
[6d5e378]113 */
114static bool decode_tga_header(void *data, size_t size, tga_t *tga)
115{
116 /* Header sanity check */
117 if (size < sizeof(tga_header_t))
118 return false;
[a35b458]119
[6d5e378]120 tga_header_t *head = (tga_header_t *) data;
[a35b458]121
[6d5e378]122 /* Image ID field */
123 tga->id_data = data + sizeof(tga_header_t);
124 tga->id_length = head->id_length;
[a35b458]125
[6d5e378]126 if (size < sizeof(tga_header_t) + tga->id_length)
127 return false;
[a35b458]128
[6d5e378]129 /* Color map type */
130 tga->cmap_type = head->cmap_type;
[a35b458]131
[6d5e378]132 /* Image type */
133 tga->img_type = head->img_type;
[a35b458]134
[6d5e378]135 /* Color map specification */
136 tga->cmap_first_entry = uint16_t_le2host(head->cmap_first_entry);
137 tga->cmap_entries = uint16_t_le2host(head->cmap_entries);
138 tga->cmap_bpp = head->cmap_bpp;
139 tga->cmap_data = tga->id_data + tga->id_length;
140 tga->cmap_length = ALIGN_UP(tga->cmap_entries * tga->cmap_bpp, 8) >> 3;
[a35b458]141
[6d5e378]142 if (size < sizeof(tga_header_t) + tga->id_length +
143 tga->cmap_length)
144 return false;
[a35b458]145
[6d5e378]146 /* Image specification */
147 tga->startx = uint16_t_le2host(head->startx);
148 tga->starty = uint16_t_le2host(head->starty);
149 tga->width = uint16_t_le2host(head->width);
150 tga->height = uint16_t_le2host(head->height);
151 tga->img_bpp = head->img_bpp;
152 tga->img_alpha_bpp = head->img_descr & 0x0f;
153 tga->img_alpha_dir = (head->img_descr & 0xf0) >> 4;
154 tga->img_data = tga->cmap_data + tga->cmap_length;
155 tga->img_length = ALIGN_UP(tga->width * tga->height * tga->img_bpp, 8) >> 3;
[a35b458]156
[6d5e378]157 if (size < sizeof(tga_header_t) + tga->id_length +
158 tga->cmap_length + tga->img_length)
159 return false;
[a35b458]160
[6d5e378]161 return true;
162}
163
164/** Decode Truevision TGA format
165 *
166 * Decode Truevision TGA format and create a surface
167 * from it. The supported variants of TGA are currently
168 * limited to uncompressed 24 bit true-color images without
169 * alpha channel.
170 *
171 * @param[in] data Memory representation of TGA.
172 * @param[in] size Size of the representation (in bytes).
173 * @param[in] flags Surface creation flags.
174 *
175 * @return Newly allocated surface with the decoded content.
176 * @return NULL on error or unsupported format.
[9250517]177 *
[6d5e378]178 */
179surface_t *decode_tga(void *data, size_t size, surface_flags_t flags)
180{
181 tga_t tga;
182 if (!decode_tga_header(data, size, &tga))
183 return NULL;
[a35b458]184
[6d5e378]185 /*
186 * Check for unsupported features.
187 */
[a35b458]188
[6d5e378]189 switch (tga.cmap_type) {
190 case CMAP_NOT_PRESENT:
191 break;
192 default:
193 /* Unsupported */
194 return NULL;
195 }
[a35b458]196
[6d5e378]197 switch (tga.img_type) {
198 case IMG_BGRA:
199 if (tga.img_bpp != 24)
200 return NULL;
201 break;
202 case IMG_GRAY:
203 if (tga.img_bpp != 8)
204 return NULL;
205 break;
206 default:
207 /* Unsupported */
208 return NULL;
209 }
[a35b458]210
[6d5e378]211 if (tga.img_alpha_bpp != 0)
212 return NULL;
[a35b458]213
[6d5e378]214 sysarg_t twidth = tga.startx + tga.width;
215 sysarg_t theight = tga.starty + tga.height;
[a35b458]216
[6d5e378]217 surface_t *surface = surface_create(twidth, theight, NULL, flags);
218 if (surface == NULL)
219 return NULL;
[a35b458]220
[6d5e378]221 /*
222 * TGA is encoded in a bottom-up manner, the true-color
223 * variant is in BGR 8:8:8 encoding.
224 */
[a35b458]225
[6d5e378]226 switch (tga.img_type) {
227 case IMG_BGRA:
228 for (sysarg_t y = tga.starty; y < theight; y++) {
229 for (sysarg_t x = tga.startx; x < twidth; x++) {
230 size_t offset =
231 ((y - tga.starty) * tga.width + (x - tga.startx)) * 3;
[a35b458]232
[6d5e378]233 pixel_t pixel =
234 bgr_888_2pixel(((uint8_t *) tga.img_data) + offset);
235 surface_put_pixel(surface, x, theight - y - 1, pixel);
236 }
237 }
238 break;
239 case IMG_GRAY:
240 for (sysarg_t y = tga.starty; y < theight; y++) {
241 for (sysarg_t x = tga.startx; x < twidth; x++) {
242 size_t offset =
243 (y - tga.starty) * tga.width + (x - tga.startx);
[a35b458]244
[6d5e378]245 pixel_t pixel =
246 gray_8_2pixel(((uint8_t *) tga.img_data) + offset);
247 surface_put_pixel(surface, x, theight - y - 1, pixel);
248 }
249 }
250 break;
251 default:
252 break;
253 }
[a35b458]254
[6d5e378]255 return surface;
256}
257
258/** Encode Truevision TGA format
259 *
260 * Encode Truevision TGA format into an array.
261 *
262 * @param[in] surface Surface to be encoded into TGA.
263 * @param[out] pdata Pointer to the resulting array.
264 * @param[out] psize Pointer to the size of the resulting array.
265 *
266 * @return True on succesful encoding.
267 * @return False on failure.
[9250517]268 *
[6d5e378]269 */
270bool encode_tga(surface_t *surface, void **pdata, size_t *psize)
271{
272 // TODO
273 return false;
274}
275
276/** @}
277 */
Note: See TracBrowser for help on using the repository browser.