~jsvoboda/helenos/dnsr

« back to all changes in this revision

Viewing changes to uspace/lib/draw/codec/tga.c

  • Committer: Jiri Svoboda
  • Date: 2012-11-11 21:31:03 UTC
  • mfrom: (1527.1.178 mainline)
  • Revision ID: jiri@wiwaxia-20121111213103-314bmkettwvlwj97
MergeĀ mainlineĀ changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright (c) 2011 Martin Decky
 
3
 * Copyright (c) 2011 Petr Koupy
3
4
 * All rights reserved.
4
5
 *
5
6
 * Redistribution and use in source and binary forms, with or without
26
27
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
 */
28
29
 
29
 
/** @addtogroup imgmap
 
30
/** @addtogroup draw
30
31
 * @{
31
32
 */
32
33
/**
37
38
#include <byteorder.h>
38
39
#include <align.h>
39
40
#include <bool.h>
40
 
#include <mem.h>
41
 
#include <as.h>
42
 
#include "imgmap.h"
43
 
 
44
 
struct imgmap {
45
 
        size_t size;
46
 
        imgmap_flags_t flags;
47
 
        sysarg_t width;
48
 
        sysarg_t height;
49
 
        visual_t visual;
50
 
        uint8_t data[];
51
 
};
52
 
 
53
 
/** RGB conversion and mask functions.
54
 
 *
55
 
 * These functions write an RGB pixel value to a memory location
56
 
 * in a predefined format. The naming convention corresponds to
57
 
 * the names of the visuals and the format created by these functions.
58
 
 * The functions use the so called network bit order (i.e. big endian)
59
 
 * with respect to their names.
60
 
 */
61
 
 
62
 
#define RED(pixel, bits)    (((pixel) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1))
63
 
#define GREEN(pixel, bits)  (((pixel) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1))
64
 
#define BLUE(pixel, bits)   (((pixel) >> (8 - (bits))) & ((1 << (bits)) - 1))
65
 
 
66
 
void pixel2rgb_0888(void *dst, pixel_t pixel)
67
 
{
68
 
        *((uint32_t *) dst) = host2uint32_t_be(
69
 
            (RED(pixel, 8) << 16) | (GREEN(pixel, 8) << 8) | (BLUE(pixel, 8)));
70
 
}
71
 
 
72
 
void pixel2bgr_0888(void *dst, pixel_t pixel)
73
 
{
74
 
        *((uint32_t *) dst) = host2uint32_t_be(
75
 
            (BLUE(pixel, 8) << 16) | (GREEN(pixel, 8) << 8) | (RED(pixel, 8)));
76
 
}
77
 
 
78
 
void pixel2rgb_8880(void *dst, pixel_t pixel)
79
 
{
80
 
        *((uint32_t *) dst) = host2uint32_t_be(
81
 
            (RED(pixel, 8) << 24) | (GREEN(pixel, 8) << 16) | (BLUE(pixel, 8) << 8));
82
 
}
83
 
 
84
 
void pixel2bgr_8880(void *dst, pixel_t pixel)
85
 
{
86
 
        *((uint32_t *) dst) = host2uint32_t_be(
87
 
            (BLUE(pixel, 8) << 24) | (GREEN(pixel, 8) << 16) | (RED(pixel, 8) << 8));
88
 
}
89
 
 
90
 
void pixel2rgb_888(void *dst, pixel_t pixel)
91
 
{
92
 
        ((uint8_t *) dst)[0] = RED(pixel, 8);
93
 
        ((uint8_t *) dst)[1] = GREEN(pixel, 8);
94
 
        ((uint8_t *) dst)[2] = BLUE(pixel, 8);
95
 
}
96
 
 
97
 
void pixel2bgr_888(void *dst, pixel_t pixel)
98
 
{
99
 
        ((uint8_t *) dst)[0] = BLUE(pixel, 8);
100
 
        ((uint8_t *) dst)[1] = GREEN(pixel, 8);
101
 
        ((uint8_t *) dst)[2] = RED(pixel, 8);
102
 
}
103
 
 
104
 
void pixel2rgb_555_be(void *dst, pixel_t pixel)
105
 
{
106
 
        *((uint16_t *) dst) = host2uint16_t_be(
107
 
            (RED(pixel, 5) << 10) | (GREEN(pixel, 5) << 5) | (BLUE(pixel, 5)));
108
 
}
109
 
 
110
 
void pixel2rgb_555_le(void *dst, pixel_t pixel)
111
 
{
112
 
        *((uint16_t *) dst) = host2uint16_t_le(
113
 
            (RED(pixel, 5) << 10) | (GREEN(pixel, 5) << 5) | (BLUE(pixel, 5)));
114
 
}
115
 
 
116
 
void pixel2rgb_565_be(void *dst, pixel_t pixel)
117
 
{
118
 
        *((uint16_t *) dst) = host2uint16_t_be(
119
 
            (RED(pixel, 5) << 11) | (GREEN(pixel, 6) << 5) | (BLUE(pixel, 5)));
120
 
}
121
 
 
122
 
void pixel2rgb_565_le(void *dst, pixel_t pixel)
123
 
{
124
 
        *((uint16_t *) dst) = host2uint16_t_le(
125
 
            (RED(pixel, 5) << 11) | (GREEN(pixel, 6) << 5) | (BLUE(pixel, 5)));
126
 
}
127
 
 
128
 
void pixel2bgr_323(void *dst, pixel_t pixel)
129
 
{
130
 
        *((uint8_t *) dst) =
131
 
            ~((RED(pixel, 3) << 5) | (GREEN(pixel, 2) << 3) | BLUE(pixel, 3));
132
 
}
133
 
 
134
 
void pixel2gray_8(void *dst, pixel_t pixel)
135
 
{
136
 
        uint32_t red = RED(pixel, 8) * 5034375;
137
 
        uint32_t green = GREEN(pixel, 8) * 9886846;
138
 
        uint32_t blue = BLUE(pixel, 8) * 1920103;
139
 
        
140
 
        *((uint8_t *) dst) = (red + green + blue) >> 24;
141
 
}
142
 
 
143
 
void visual_mask_0888(void *dst, bool mask)
144
 
{
145
 
        pixel2bgr_0888(dst, mask ? 0xffffff : 0);
146
 
}
147
 
 
148
 
void visual_mask_8880(void *dst, bool mask)
149
 
{
150
 
        pixel2bgr_8880(dst, mask ? 0xffffff : 0);
151
 
}
152
 
 
153
 
void visual_mask_888(void *dst, bool mask)
154
 
{
155
 
        pixel2bgr_888(dst, mask ? 0xffffff : 0);
156
 
}
157
 
 
158
 
void visual_mask_555(void *dst, bool mask)
159
 
{
160
 
        pixel2rgb_555_be(dst, mask ? 0xffffff : 0);
161
 
}
162
 
 
163
 
void visual_mask_565(void *dst, bool mask)
164
 
{
165
 
        pixel2rgb_565_be(dst, mask ? 0xffffff : 0);
166
 
}
167
 
 
168
 
void visual_mask_323(void *dst, bool mask)
169
 
{
170
 
        pixel2bgr_323(dst, mask ? 0x0 : ~0x0);
171
 
}
172
 
 
173
 
void visual_mask_8(void *dst, bool mask)
174
 
{
175
 
        pixel2gray_8(dst, mask ? 0xffffff : 0);
176
 
}
177
 
 
178
 
pixel_t rgb_0888_2pixel(void *src)
179
 
{
180
 
        return (uint32_t_be2host(*((uint32_t *) src)) & 0xffffff);
181
 
}
182
 
 
183
 
pixel_t bgr_0888_2pixel(void *src)
184
 
{
185
 
        uint32_t val = uint32_t_be2host(*((uint32_t *) src));
186
 
        return (((val & 0xff0000) >> 16) | (val & 0xff00) | ((val & 0xff) << 16));
187
 
}
188
 
 
189
 
pixel_t rgb_8880_2pixel(void *src)
190
 
{
191
 
        return (uint32_t_be2host(*((uint32_t *) src)) >> 8);
192
 
}
193
 
 
194
 
pixel_t bgr_8880_2pixel(void *src)
195
 
{
196
 
        uint32_t val = uint32_t_be2host(*((uint32_t *) src));
197
 
        return (((val & 0xff000000) >> 24) | ((val & 0xff0000) >> 8) | ((val & 0xff00) << 8));
198
 
}
199
 
 
200
 
pixel_t rgb_888_2pixel(void *src)
201
 
{
202
 
        uint8_t red = ((uint8_t *) src)[0];
203
 
        uint8_t green = ((uint8_t *) src)[1];
204
 
        uint8_t blue = ((uint8_t *) src)[2];
205
 
        
206
 
        return ((red << 16) | (green << 8) | (blue));
207
 
}
208
 
 
209
 
pixel_t bgr_888_2pixel(void *src)
210
 
{
211
 
        uint8_t blue = ((uint8_t *) src)[0];
212
 
        uint8_t green = ((uint8_t *) src)[1];
213
 
        uint8_t red = ((uint8_t *) src)[2];
214
 
        
215
 
        return ((red << 16) | (green << 8) | (blue));
216
 
}
217
 
 
218
 
pixel_t rgb_555_be_2pixel(void *src)
219
 
{
220
 
        uint16_t val = uint16_t_be2host(*((uint16_t *) src));
221
 
        return (((val & 0x7c00) << 9) | ((val & 0x3e0) << 6) | ((val & 0x1f) << 3));
222
 
}
223
 
 
224
 
pixel_t rgb_555_le_2pixel(void *src)
225
 
{
226
 
        uint16_t val = uint16_t_le2host(*((uint16_t *) src));
227
 
        return (((val & 0x7c00) << 9) | ((val & 0x3e0) << 6) | ((val & 0x1f) << 3));
228
 
}
229
 
 
230
 
pixel_t rgb_565_be_2pixel(void *src)
231
 
{
232
 
        uint16_t val = uint16_t_be2host(*((uint16_t *) src));
233
 
        return (((val & 0xf800) << 8) | ((val & 0x7e0) << 5) | ((val & 0x1f) << 3));
234
 
}
235
 
 
236
 
pixel_t rgb_565_le_2pixel(void *src)
237
 
{
238
 
        uint16_t val = uint16_t_le2host(*((uint16_t *) src));
239
 
        return (((val & 0xf800) << 8) | ((val & 0x7e0) << 5) | ((val & 0x1f) << 3));
240
 
}
241
 
 
242
 
pixel_t bgr_323_2pixel(void *src)
243
 
{
244
 
        uint8_t val = ~(*((uint8_t *) src));
245
 
        return (((val & 0xe0) << 16) | ((val & 0x18) << 11) | ((val & 0x7) << 5));
246
 
}
247
 
 
248
 
pixel_t gray_8_2pixel(void *src)
249
 
{
250
 
        uint8_t val = *((uint8_t *) src);
251
 
        return ((val << 16) | (val << 8) | (val));
252
 
}
 
41
#include <pixconv.h>
 
42
#include "tga.h"
253
43
 
254
44
typedef struct {
255
45
        uint8_t id_length;
319
109
 *
320
110
 * @return True on succesful decoding.
321
111
 * @return False on failure.
322
 
 *
323
112
 */
324
113
static bool decode_tga_header(void *data, size_t size, tga_t *tga)
325
114
{
371
160
        return true;
372
161
}
373
162
 
374
 
void imgmap_put_pixel(imgmap_t *imgmap, sysarg_t x, sysarg_t y, pixel_t pixel)
375
 
{
376
 
        if ((x >= imgmap->width) || (y >= imgmap->height))
377
 
                return;
378
 
        
379
 
        size_t offset = y * imgmap->width + x;
380
 
        
381
 
        switch (imgmap->visual) {
382
 
        case VISUAL_RGB_0_8_8_8:
383
 
                pixel2rgb_0888(((uint32_t *) imgmap->data) + offset, pixel);
384
 
                break;
385
 
        default:
386
 
                break;
387
 
        }
388
 
}
389
 
 
390
 
pixel_t imgmap_get_pixel(imgmap_t *imgmap, sysarg_t x, sysarg_t y)
391
 
{
392
 
        if ((x >= imgmap->width) || (y >= imgmap->height))
393
 
                return 0;
394
 
        
395
 
        size_t offset = y * imgmap->width + x;
396
 
        
397
 
        switch (imgmap->visual) {
398
 
        case VISUAL_RGB_0_8_8_8:
399
 
                return rgb_0888_2pixel(((uint32_t *) imgmap->data) + offset);
400
 
        default:
401
 
                return 0;
402
 
        }
403
 
}
404
 
 
405
 
imgmap_t *imgmap_create(sysarg_t width, sysarg_t height, visual_t visual,
406
 
    imgmap_flags_t flags)
407
 
{
408
 
        size_t bsize;
409
 
        
410
 
        switch (visual) {
411
 
        case VISUAL_RGB_0_8_8_8:
412
 
                bsize = (width * height) << 2;
413
 
                break;
414
 
        default:
415
 
                return NULL;
416
 
        }
417
 
        
418
 
        size_t size = sizeof(imgmap_t) + bsize;
419
 
        imgmap_t *imgmap;
420
 
        
421
 
        if ((flags & IMGMAP_FLAG_SHARED) == IMGMAP_FLAG_SHARED) {
422
 
                imgmap = (imgmap_t *) as_area_create(AS_AREA_ANY, size,
423
 
                    AS_AREA_READ | AS_AREA_WRITE);
424
 
                if (imgmap == AS_MAP_FAILED)
425
 
                        return NULL;
426
 
        } else {
427
 
                imgmap = (imgmap_t *) malloc(size);
428
 
                if (imgmap == NULL)
429
 
                        return NULL;
430
 
        }
431
 
        
432
 
        imgmap->size = size;
433
 
        imgmap->flags = flags;
434
 
        imgmap->width = width;
435
 
        imgmap->height = height;
436
 
        imgmap->visual = visual;
437
 
        
438
 
        memset(imgmap->data, 0, bsize);
439
 
        
440
 
        return imgmap;
441
 
}
442
 
 
443
163
/** Decode Truevision TGA format
444
164
 *
445
 
 * Decode Truevision TGA format and create an image map
 
165
 * Decode Truevision TGA format and create a surface
446
166
 * from it. The supported variants of TGA are currently
447
167
 * limited to uncompressed 24 bit true-color images without
448
168
 * alpha channel.
449
169
 *
450
170
 * @param[in] data  Memory representation of TGA.
451
171
 * @param[in] size  Size of the representation (in bytes).
452
 
 * @param[in] flags Image map creation flags.
 
172
 * @param[in] flags Surface creation flags.
453
173
 *
454
 
 * @return Newly allocated image map.
 
174
 * @return Newly allocated surface with the decoded content.
455
175
 * @return NULL on error or unsupported format.
456
 
 *
457
176
 */
458
 
imgmap_t *imgmap_decode_tga(void *data, size_t size, imgmap_flags_t flags)
 
177
surface_t *decode_tga(void *data, size_t size, surface_flags_t flags)
459
178
{
460
179
        tga_t tga;
461
180
        if (!decode_tga_header(data, size, &tga))
493
212
        sysarg_t twidth = tga.startx + tga.width;
494
213
        sysarg_t theight = tga.starty + tga.height;
495
214
        
496
 
        imgmap_t *imgmap = imgmap_create(twidth, theight, VISUAL_RGB_0_8_8_8,
497
 
            flags);
498
 
        if (imgmap == NULL)
 
215
        surface_t *surface = surface_create(twidth, theight, NULL, flags);
 
216
        if (surface == NULL)
499
217
                return NULL;
500
218
        
501
219
        /*
512
230
                                
513
231
                                pixel_t pixel =
514
232
                                    bgr_888_2pixel(((uint8_t *) tga.img_data) + offset);
515
 
                                imgmap_put_pixel(imgmap, x, theight - y - 1, pixel);
 
233
                                surface_put_pixel(surface, x, theight - y - 1, pixel);
516
234
                        }
517
235
                }
518
236
                break;
524
242
                                
525
243
                                pixel_t pixel =
526
244
                                    gray_8_2pixel(((uint8_t *) tga.img_data) + offset);
527
 
                                imgmap_put_pixel(imgmap, x, theight - y - 1, pixel);
 
245
                                surface_put_pixel(surface, x, theight - y - 1, pixel);
528
246
                        }
529
247
                }
530
248
                break;
532
250
                break;
533
251
        }
534
252
        
535
 
        return imgmap;
 
253
        return surface;
536
254
}
537
255
 
538
 
void imgmap_get_resolution(imgmap_t *imgmap, sysarg_t *width, sysarg_t *height)
 
256
/** Encode Truevision TGA format
 
257
 *
 
258
 * Encode Truevision TGA format into an array.
 
259
 *
 
260
 * @param[in]  surface Surface to be encoded into TGA.
 
261
 * @param[out] pdata   Pointer to the resulting array.
 
262
 * @param[out] psize   Pointer to the size of the resulting array.
 
263
 *
 
264
 * @return True on succesful encoding.
 
265
 * @return False on failure.
 
266
 */
 
267
bool encode_tga(surface_t *surface, void **pdata, size_t *psize)
539
268
{
540
 
        assert(width);
541
 
        assert(height);
542
 
        
543
 
        *width = imgmap->width;
544
 
        *height = imgmap->height;
 
269
        // TODO
 
270
        return false;
545
271
}
546
272
 
547
273
/** @}