1/*
2 * BRender PIX (.pix) image decoder
3 * Copyright (c) 2012 Aleksi Nurmi
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22/* Tested against samples from I-War / Independence War and Defiance. */
23
24#include "libavutil/imgutils.h"
25
26#include "avcodec.h"
27#include "bytestream.h"
28#include "internal.h"
29
30#define HEADER1_CHUNK    0x03
31#define HEADER2_CHUNK    0x3D
32#define IMAGE_DATA_CHUNK 0x21
33
34/* In 8-bit colour mode, 256 colours are available at any time. Which 256
35 * colours are available is determined by the contents of the hardware palette
36 * (or CLUT). In this case, the palette supplied with BRender (std.pal) has
37 * been loaded into the CLUT.
38 *
39 * The 256 colours in std.pal are divided into seven ranges, or `colour ramps'.
40 * The first 64 colours represent shades of grey ranging from very dark grey
41 * (black) to very light grey (white). The following colours are 32-element
42 * ramps for six colours as shown below.
43 */
44static const uint32_t std_pal_table[256] = {
45    // gray
46    0xFF000000, 0xFF030303, 0xFF060606, 0xFF090909, 0xFF0C0C0C, 0xFF0F0F0F,
47    0xFF121212, 0xFF151515, 0xFF181818, 0xFF1B1B1B, 0xFF1E1E1E, 0xFF212121,
48    0xFF242424, 0xFF272727, 0xFF2A2A2A, 0xFF2D2D2D, 0xFF313131, 0xFF343434,
49    0xFF373737, 0xFF3A3A3A, 0xFF3D3D3D, 0xFF404040, 0xFF434343, 0xFF464646,
50    0xFF494949, 0xFF4C4C4C, 0xFF4F4F4F, 0xFF525252, 0xFF555555, 0xFF585858,
51    0xFF5B5B5B, 0xFF5E5E5E, 0xFF626262, 0xFF656565, 0xFF686868, 0xFF6B6B6B,
52    0xFF6E6E6E, 0xFF717171, 0xFF747474, 0xFF777777, 0xFF7A7A7A, 0xFF7D7D7D,
53    0xFF808080, 0xFF838383, 0xFF868686, 0xFF898989, 0xFF8C8C8C, 0xFF8F8F8F,
54    0xFF939393, 0xFF999999, 0xFFA0A0A0, 0xFFA7A7A7, 0xFFAEAEAE, 0xFFB4B4B4,
55    0xFFBBBBBB, 0xFFC2C2C2, 0xFFC9C9C9, 0xFFCFCFCF, 0xFFD6D6D6, 0xFFDDDDDD,
56    0xFFE4E4E4, 0xFFEAEAEA, 0xFFF1F1F1, 0xFFF8F8F8,
57
58    // blue
59    0xFF000000, 0xFF020209, 0xFF050513, 0xFF07071D, 0xFF0A0A27, 0xFF0C0C31,
60    0xFF0F0F3B, 0xFF111145, 0xFF14144F, 0xFF161659, 0xFF181863, 0xFF1B1B6D,
61    0xFF1E1E77, 0xFF202080, 0xFF22228A, 0xFF252594, 0xFF28289E, 0xFF2A2AA8,
62    0xFF2D2DB2, 0xFF2F2FBC, 0xFF3131C6, 0xFF3434D0, 0xFF3737DA, 0xFF3939E4,
63    0xFF3C3CEE, 0xFF5454F0, 0xFF6C6CF2, 0xFF8585F4, 0xFF9D9DF6, 0xFFB5B5F8,
64    0xFFCECEFA, 0xFFE6E6FC,
65
66    // green
67    0xFF000000, 0xFF020902, 0xFF051305, 0xFF071D07, 0xFF0A270A, 0xFF0C310C,
68    0xFF0F3B0F, 0xFF114511, 0xFF144F14, 0xFF165916, 0xFF186318, 0xFF1B6D1B,
69    0xFF1E771E, 0xFF208020, 0xFF228A22, 0xFF259425, 0xFF289E28, 0xFF2AA82A,
70    0xFF2DB22D, 0xFF2FBC2F, 0xFF31C631, 0xFF34D034, 0xFF37DA37, 0xFF39E439,
71    0xFF3CEE3C, 0xFF54F054, 0xFF6CF26C, 0xFF85F485, 0xFF9DF69D, 0xFFB5F8B5,
72    0xFFCEFACE, 0xFFE6FCE6,
73
74    // cyan
75    0xFF000000, 0xFF020909, 0xFF051313, 0xFF071D1D, 0xFF0A2727, 0xFF0C3131,
76    0xFF0F3B3B, 0xFF114545, 0xFF144F4F, 0xFF165959, 0xFF186363, 0xFF1B6D6D,
77    0xFF1E7777, 0xFF208080, 0xFF228A8A, 0xFF259494, 0xFF289E9E, 0xFF2AA8A8,
78    0xFF2DB2B2, 0xFF2FBCBC, 0xFF31C6C6, 0xFF34D0D0, 0xFF37DADA, 0xFF39E4E4,
79    0xFF3CEEEE, 0xFF54F0F0, 0xFF6CF2F2, 0xFF85F4F4, 0xFF9DF6F6, 0xFFB5F8F8,
80    0xFFCEFAFA, 0xFFE6FCFC,
81
82    // red
83    0xFF000000, 0xFF090202, 0xFF130505, 0xFF1D0707, 0xFF270A0A, 0xFF310C0C,
84    0xFF3B0F0F, 0xFF451111, 0xFF4F1414, 0xFF591616, 0xFF631818, 0xFF6D1B1B,
85    0xFF771E1E, 0xFF802020, 0xFF8A2222, 0xFF942525, 0xFF9E2828, 0xFFA82A2A,
86    0xFFB22D2D, 0xFFBC2F2F, 0xFFC63131, 0xFFD03434, 0xFFDA3737, 0xFFE43939,
87    0xFFEE3C3C, 0xFFF05454, 0xFFF26C6C, 0xFFF48585, 0xFFF69D9D, 0xFFF8B5B5,
88    0xFFFACECE, 0xFFFCE6E6,
89
90    // magenta
91    0xFF000000, 0xFF090209, 0xFF130513, 0xFF1D071D, 0xFF270A27, 0xFF310C31,
92    0xFF3B0F3B, 0xFF451145, 0xFF4F144F, 0xFF591659, 0xFF631863, 0xFF6D1B6D,
93    0xFF771E77, 0xFF802080, 0xFF8A228A, 0xFF942594, 0xFF9E289E, 0xFFA82AA8,
94    0xFFB22DB2, 0xFFBC2FBC, 0xFFC631C6, 0xFFD034D0, 0xFFDA37DA, 0xFFE439E4,
95    0xFFEE3CEE, 0xFFF054F0, 0xFFF26CF2, 0xFFF485F4, 0xFFF69DF6, 0xFFF8B5F8,
96    0xFFFACEFA, 0xFFFCE6FC,
97
98    // yellow
99    0xFF000000, 0xFF090902, 0xFF131305, 0xFF1D1D07, 0xFF27270A, 0xFF31310C,
100    0xFF3B3B0F, 0xFF454511, 0xFF4F4F14, 0xFF595916, 0xFF636318, 0xFF6D6D1B,
101    0xFF77771E, 0xFF808020, 0xFF8A8A22, 0xFF949425, 0xFF9E9E28, 0xFFA8A82A,
102    0xFFB2B22D, 0xFFBCBC2F, 0xFFC6C631, 0xFFD0D034, 0xFFDADA37, 0xFFE4E439,
103    0xFFEEEE3C, 0xFFF0F054, 0xFFF2F26C, 0xFFF4F485, 0xFFF6F69D, 0xFFF8F8B5,
104    0xFFFAFACE, 0xFFFCFCE6,
105};
106
107typedef struct PixHeader {
108    int width;
109    int height;
110    int format;
111} PixHeader;
112
113static int pix_decode_header(PixHeader *out, GetByteContext *pgb)
114{
115    unsigned int header_len = bytestream2_get_be32(pgb);
116
117    out->format = bytestream2_get_byte(pgb);
118    bytestream2_skip(pgb, 2);
119    out->width  = bytestream2_get_be16(pgb);
120    out->height = bytestream2_get_be16(pgb);
121
122    // the header is at least 11 bytes long; we read the first 7
123    if (header_len < 11)
124        return AVERROR_INVALIDDATA;
125
126    // skip the rest of the header
127    bytestream2_skip(pgb, header_len - 7);
128
129    return 0;
130}
131
132static int pix_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
133                            AVPacket *avpkt)
134{
135    AVFrame *frame = data;
136
137    int ret, i;
138    GetByteContext gb;
139
140    unsigned int bytes_pp;
141    unsigned int magic[4];
142    unsigned int chunk_type;
143    unsigned int data_len;
144    unsigned int bytes_per_scanline;
145    unsigned int bytes_left;
146    PixHeader hdr;
147
148    bytestream2_init(&gb, avpkt->data, avpkt->size);
149
150    magic[0] = bytestream2_get_be32(&gb);
151    magic[1] = bytestream2_get_be32(&gb);
152    magic[2] = bytestream2_get_be32(&gb);
153    magic[3] = bytestream2_get_be32(&gb);
154
155    if (magic[0] != 0x12 ||
156        magic[1] != 0x08 ||
157        magic[2] != 0x02 ||
158        magic[3] != 0x02) {
159        av_log(avctx, AV_LOG_ERROR, "Not a BRender PIX file.\n");
160        return AVERROR_INVALIDDATA;
161    }
162
163    chunk_type = bytestream2_get_be32(&gb);
164    if (chunk_type != HEADER1_CHUNK && chunk_type != HEADER2_CHUNK) {
165        av_log(avctx, AV_LOG_ERROR, "Invalid chunk type %d.\n", chunk_type);
166        return AVERROR_INVALIDDATA;
167    }
168
169    ret = pix_decode_header(&hdr, &gb);
170    if (ret < 0) {
171        av_log(avctx, AV_LOG_ERROR, "Invalid header length.\n");
172        return ret;
173    }
174    switch (hdr.format) {
175    case 3:
176        avctx->pix_fmt = AV_PIX_FMT_PAL8;
177        bytes_pp = 1;
178        break;
179    case 4:
180        avctx->pix_fmt = AV_PIX_FMT_RGB555BE;
181        bytes_pp = 2;
182        break;
183    case 5:
184        avctx->pix_fmt = AV_PIX_FMT_RGB565BE;
185        bytes_pp = 2;
186        break;
187    case 6:
188        avctx->pix_fmt = AV_PIX_FMT_RGB24;
189        bytes_pp = 3;
190        break;
191    case 7:
192        avctx->pix_fmt = AV_PIX_FMT_0RGB;
193        bytes_pp = 4;
194        break;
195    case 8: // ARGB
196        avctx->pix_fmt = AV_PIX_FMT_ARGB;
197        bytes_pp = 4;
198        break;
199    case 18:
200        avctx->pix_fmt = AV_PIX_FMT_Y400A;
201        bytes_pp = 2;
202        break;
203    default:
204        avpriv_request_sample(avctx, "Format %d", hdr.format);
205        return AVERROR_PATCHWELCOME;
206    }
207
208    if ((ret = ff_set_dimensions(avctx, hdr.width, hdr.height)) < 0)
209        return ret;
210
211    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
212        return ret;
213
214    chunk_type = bytestream2_get_be32(&gb);
215
216    if (avctx->pix_fmt == AV_PIX_FMT_PAL8 &&
217        (chunk_type == HEADER1_CHUNK ||
218         chunk_type == HEADER2_CHUNK)) {
219        /* read palette data from data[1] */
220        PixHeader palhdr;
221        uint32_t *pal_out = (uint32_t *)frame->data[1];
222
223        ret = pix_decode_header(&palhdr, &gb);
224        if (ret < 0) {
225            av_log(avctx, AV_LOG_ERROR, "Invalid palette header length.\n");
226            return ret;
227        }
228        if (palhdr.format != 7)
229            avpriv_request_sample(avctx, "Palette not in RGB format");
230
231        chunk_type = bytestream2_get_be32(&gb);
232        data_len = bytestream2_get_be32(&gb);
233        bytestream2_skip(&gb, 8);
234        if (chunk_type != IMAGE_DATA_CHUNK || data_len != 1032 ||
235            bytestream2_get_bytes_left(&gb) < 1032) {
236            av_log(avctx, AV_LOG_ERROR, "Invalid palette data.\n");
237            return AVERROR_INVALIDDATA;
238        }
239        // palette data is surrounded by 8 null bytes (both top and bottom)
240        // convert 0RGB to machine endian format (ARGB32)
241        for (i = 0; i < 256; ++i)
242            *pal_out++ = (0xFFU << 24) | bytestream2_get_be32u(&gb);
243        bytestream2_skip(&gb, 8);
244
245        frame->palette_has_changed = 1;
246
247        chunk_type = bytestream2_get_be32(&gb);
248    } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
249        /* no palette supplied, use the default one */
250        uint32_t *pal_out = (uint32_t *)frame->data[1];
251
252        // TODO: add an AVOption to load custom palette files
253        av_log(avctx, AV_LOG_WARNING,
254               "Using default palette, colors might be off.\n");
255        memcpy(pal_out, std_pal_table, sizeof(uint32_t) * 256);
256
257        frame->palette_has_changed = 1;
258    }
259
260    data_len = bytestream2_get_be32(&gb);
261    bytestream2_skip(&gb, 8);
262
263    // read the image data to the buffer
264    bytes_per_scanline = bytes_pp * hdr.width;
265    bytes_left = bytestream2_get_bytes_left(&gb);
266
267    if (chunk_type != IMAGE_DATA_CHUNK || data_len != bytes_left ||
268        bytes_left / bytes_per_scanline < hdr.height) {
269        av_log(avctx, AV_LOG_ERROR, "Invalid image data.\n");
270        return AVERROR_INVALIDDATA;
271    }
272
273    av_image_copy_plane(frame->data[0], frame->linesize[0],
274                        avpkt->data + bytestream2_tell(&gb),
275                        bytes_per_scanline,
276                        bytes_per_scanline, hdr.height);
277
278    frame->pict_type = AV_PICTURE_TYPE_I;
279    frame->key_frame = 1;
280    *got_frame = 1;
281
282    return avpkt->size;
283}
284
285AVCodec ff_brender_pix_decoder = {
286    .name         = "brender_pix",
287    .long_name    = NULL_IF_CONFIG_SMALL("BRender PIX image"),
288    .type         = AVMEDIA_TYPE_VIDEO,
289    .id           = AV_CODEC_ID_BRENDER_PIX,
290    .decode       = pix_decode_frame,
291    .capabilities = CODEC_CAP_DR1,
292};
293