Merge "Run Draw*BaseVertex if EXT_draw_elements_base_vertex is present"
[platform/upstream/VK-GL-CTS.git] / framework / delibs / deimage / deTarga.c
1 /*-------------------------------------------------------------------------
2  * drawElements Image Library
3  * --------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Targa file operations.
22  *//*--------------------------------------------------------------------*/
23
24 #include "deImage.h"
25 #include "deMemory.h"
26 #include "deInt32.h"
27
28 #include <stdio.h>
29
30 deImage* deImage_loadTarga (const char* fileName)
31 {
32         deImage*        image = DE_NULL;
33         FILE*           file;
34
35         file = fopen(fileName, "rb");
36
37         if (file != DE_NULL)
38         {
39                 int                             bytesRead;
40                 int                             width;
41                 int                             height;
42                 int                             bufSize;
43                 int                             stride;
44                 int                             bitsPerPixel;
45                 deUint8*                buffer;
46                 deImageFormat   format;
47                 deBool                  yFlipped;
48
49                 deUint8 tgaHeader[18];
50
51                 bytesRead = (int)fread(&tgaHeader, 1, 18, file);
52                 DE_TEST_ASSERT(bytesRead == 18);
53                 DE_TEST_ASSERT(tgaHeader[2] == 2);                                                              /* truecolor, no encoding */
54                 DE_TEST_ASSERT(tgaHeader[17] == 0x00 || tgaHeader[17] == 0x20); /* both y-directions supported, non-interlaced */
55
56                 yFlipped = (tgaHeader[17] & 0x20) == 0;
57
58                 /* Decode header. */
59                 width                   = (int)(tgaHeader[12]) | ((int)(tgaHeader[13]) << 8);
60                 height                  = (int)(tgaHeader[14]) | ((int)(tgaHeader[15]) << 8);
61                 bitsPerPixel    = tgaHeader[16];
62                 stride                  = width * bitsPerPixel / 8;
63
64                 /* Allocate buffer. */
65                 bufSize = stride;
66                 buffer  = deMalloc(bufSize);
67                 DE_TEST_ASSERT(buffer);
68
69                 /* Figure out format. */
70                 DE_TEST_ASSERT(bitsPerPixel == 24 || bitsPerPixel == 32);
71                 format = (bitsPerPixel == 32) ? DE_IMAGEFORMAT_ARGB8888 : DE_IMAGEFORMAT_XRGB8888;
72
73                 /* Create image. */
74                 image = deImage_create(width, height, format);
75                 DE_TEST_ASSERT(image);
76
77                 /* Copy pixel data. */
78                 {
79                         int     bpp = 4;
80                         int     x, y;
81
82                         for (y = 0; y < height; y++)
83                         {
84                                 const deUint8*  src             = buffer;
85                                 int                             dstY    = yFlipped ? (height-1 - y) : y;
86                                 deARGB*                 dst             = (deUint32*)((deUint8*)image->pixels + dstY*image->width*bpp);
87                                 fread(buffer, 1, bufSize, file);
88
89                                 if (bitsPerPixel == 24)
90                                 {
91                                         for (x = 0; x < width; x++)
92                                         {
93                                                 deUint8 b = *src++;
94                                                 deUint8 g = *src++;
95                                                 deUint8 r = *src++;
96                                                 *dst++ = deARGB_set(r, g, b, 0xFF);
97                                         }
98                                 }
99                                 else
100                                 {
101                                         /* \todo [petri] Component order? */
102                                         deUint8 a = *src++;
103                                         deUint8 b = *src++;
104                                         deUint8 g = *src++;
105                                         deUint8 r = *src++;
106                                         DE_ASSERT(bitsPerPixel == 32);
107                                         *dst++ = deARGB_set(r, g, b, a);
108                                 }
109                         }
110                 }
111
112                 deFree(buffer);
113                 fclose(file);
114         }
115
116         return image;
117 }
118
119 deBool deImage_saveTarga (const deImage* image, const char* fileName)
120 {
121         deImage*        imageCopy       = DE_NULL;
122         int                     width           = image->width;
123         int                     height          = image->height;
124         char            tgaHeader[18];
125         FILE*           file;
126
127         /* \todo [petri] Handle non-alpha images. */
128         if (image->format != DE_IMAGEFORMAT_ARGB8888)
129         {
130                 imageCopy = deImage_convertFormat(image, DE_IMAGEFORMAT_ARGB8888);
131                 if (!imageCopy)
132                         return DE_FALSE;
133
134                 image = imageCopy;
135         }
136
137         file = fopen(fileName, "wb");
138         if (!file)
139                 return DE_FALSE;
140
141         /* Set unused fields of header to 0 */
142         memset(tgaHeader, 0, sizeof(tgaHeader));
143
144         tgaHeader[1] = 0;       /* no palette */
145         tgaHeader[2] = 2;       /* uncompressed RGB */
146
147         tgaHeader[12] = (char)(width & 0xFF);
148         tgaHeader[13] = (char)(width >> 8);
149         tgaHeader[14] = (char)(height & 0xFF);
150         tgaHeader[15] = (char)(height >> 8);
151         tgaHeader[16] = 24;             /* bytes per pixel */
152         tgaHeader[17] = 0x20;   /* Top-down, non-interlaced */
153
154         fwrite(tgaHeader, 1, 18, file);
155
156         /* Store pixels. */
157         {
158                 const deUint32* pixels  = image->pixels;
159                 int                             ndx;
160
161                 for (ndx = 0; ndx < width * height; ndx++)
162                 {
163                         deUint32 c = pixels[ndx];
164                         fputc((deUint8)(c>>0), file);
165                         fputc((deUint8)(c>>8), file);
166                         fputc((deUint8)(c>>16), file);
167                 }
168         }
169
170         /* Cleanup and return. */
171         fclose(file);
172         if (imageCopy)
173                 deImage_destroy(imageCopy);
174
175         return DE_TRUE;
176 }