28 #define PALDATA_FOLLOWS_TILEDATA 4
29 #define HAVE_COMPRESSED_TILEMAP 32
30 #define HAVE_TILEMAP 128
74 memset(pal, 0, 16 *
sizeof(*pal));
77 for (
int RGBIndex = 0; RGBIndex < 3; RGBIndex++) {
84 for (
int RGBIndex = 0; RGBIndex < 3; RGBIndex++) {
91 for (
int RGBIndex = 0; RGBIndex < 3; RGBIndex++) {
108 const uint8_t *tt =
s->tileindex_data;
110 for (
int y = 0; y <
s->tiles_h; y++) {
111 for (
int x = 0; x <
s->tiles_w; x++) {
112 int pal_idx =
s->palmapindex_data[y *
s->tiles_w + x] * 16;
115 for (
int yy = 0; yy < 8; yy++) {
116 for (
int xx = 0; xx < 8; xx++)
117 dst[xx] = pal_idx + tt[xx];
139 for (
int y = 0; y <
s->tiles_h; y++) {
140 for (
int x = 0; x <
s->tiles_w; x++) {
143 int flip_x = (tilemap >> 11) & 1;
144 int flip_y = (tilemap >> 12) & 1;
145 int tindex =
av_clip((tilemap & 511) - 1, 0,
s->nb_tiles - 1);
146 const uint8_t *tt =
s->tileindex_data + tindex * 64;
147 int pal_idx = ((tilemap >> 13) & 3) * 16;
150 if (!flip_x && !flip_y) {
151 memcpy(tile, tt, 64);
152 }
else if (flip_x && flip_y) {
153 for (
int i = 0;
i < 8;
i++) {
154 for (
int j = 0; j < 8; j++)
155 tile[
i * 8 + j] = tt[(7 -
i) * 8 + 7 - j];
158 for (
int i = 0;
i < 8;
i++) {
159 for (
int j = 0; j < 8; j++)
160 tile[
i * 8 + j] = tt[
i * 8 + 7 - j];
163 for (
int i = 0;
i < 8;
i++) {
164 for (
int j = 0; j < 8; j++)
165 tile[
i * 8 + j] = tt[(7 -
i) * 8 + j];
169 for (
int yy = 0; yy < 8; yy++) {
170 for (
int xx = 0; xx < 8; xx++)
171 dst[xx] = pal_idx + tile[xx + yy * 8];
188 for (
int yy = 0; yy < 8; yy++) {
189 for (
int xx = 0; xx < 8; xx++)
203 int dst_size,
int shift,
int plus)
208 uint16_t displace,
header = bytestream2_get_be16(gb);
211 for (
int i = 0;
i < 16;
i++) {
214 if (oi + 2 < dst_size) {
215 dst[oi++] = bytestream2_get_byte(gb);
216 dst[oi++] = bytestream2_get_byte(gb);
220 displace = bytestream2_get_be16(gb);
221 count = displace >>
shift;
227 dst[oi++] = bytestream2_get_byte(gb);
235 if (oi < offset || oi + count * 2 > dst_size)
237 for (
int j = 0; j < count * 2; j++) {
238 dst[oi] = dst[oi -
offset];
254 const int bits = (
s->nb_pal + 1) / 2;
265 for (
int y = 0; y <
s->tiles_h; y++) {
266 uint8_t *dst =
s->palmapindex_data + y *
s->tiles_w;
268 for (
int x = 0; x <
s->tiles_w; x++)
290 for (
int n = 0; n <
s->nb_tiles; n++) {
291 uint8_t *dst =
s->tileindex_data + n * 64;
293 for (
int yy = 0; yy < 8; yy++) {
294 for (
int xx = 0; xx < 8; xx++)
301 for (
int i = 0;
i <
s->nb_tiles &&
s->swap;
i++) {
302 uint8_t *dst =
s->tileindex_data +
i * 64;
304 for (
int j = 8; j < 64; j += 16) {
305 for (
int k = 0; k < 8; k += 2)
321 if (avpkt->
size <= 14)
324 s->flags = avpkt->
data[8];
325 s->nb_pal = avpkt->
data[9];
326 s->tiles_w = avpkt->
data[10];
327 s->tiles_h = avpkt->
data[11];
334 s->tiles_h * 8)) < 0)
339 if (!
s->tileindex_data)
343 s->tiles_w *
s->tiles_h);
344 if (!
s->palmapindex_data)
352 type = bytestream2_get_byte(gb);
355 if (
s->nb_tiles >
s->tiles_w *
s->tiles_h)
391 int offset =
s->metadata_size, left;
396 for (
int i = 0;
i < 3;
i++)
397 sizes[
i] = bytestream2_get_be16(gb);
399 for (
int i = 0;
i < 3;
i++) {
401 int raw =
size >> 15;
403 size &= (1 << 15) - 1;
422 sizeof(
s->uncompressed) -
offset,
s->shift,
s->plus);
433 if (
sizeof(
s->uncompressed) -
offset < left)
451 sizeof(
s->uncompressed) -
s->metadata_size,
s->shift,
s->plus);
457 s->tiledata_size =
s->nb_tiles * 32;
458 s->paldata_size =
s->nb_pal * 18;
461 s->palmapdata_offset = (
s->flags &
HAVE_TILEMAP) ? -1 :
s->paldata_offset +
s->paldata_size;
462 s->palmapdata_size = (
s->flags &
HAVE_TILEMAP) ||
s->nb_pal < 2 ? 0 : (
s->tiles_w *
s->tiles_h * ((
s->nb_pal + 1) / 2) + 7) / 8;
463 s->tilemapdata_size = (
s->flags &
HAVE_TILEMAP) ?
s->tiles_w *
s->tiles_h * 2 : 0;
464 s->tilemapdata_offset = (
s->flags &
HAVE_TILEMAP) ?
s->paldata_offset +
s->paldata_size: -1;
467 for (
int n = 0; n <
s->nb_pal; n++) {
473 if (
s->tiledata_size > 0) {
479 if (
s->palmapdata_size > 0) {
485 if (
s->palmapdata_size > 0 &&
s->tiledata_size > 0) {
489 }
else if (
s->tilemapdata_size > 0 &&
s->tiledata_size > 0) {
493 }
else if (
s->tiledata_size > 0) {
519 s->tileindex_size = 0;
522 s->palmapindex_size = 0;
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Libavcodec external API header.
static av_cold int init(AVCodecContext *avctx)
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
common internal and external API header
#define FFSWAP(type, a, b)
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
bitstream reader API header.
static unsigned int get_bits1(GetBitContext *s)
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
Same behaviour av_fast_malloc but the buffer has additional AV_INPUT_BUFFER_PADDING_SIZE at the end w...
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
@ AV_PICTURE_TYPE_I
Intra.
static const int sizes[][2]
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
static int decode_palmapdata(AVCodecContext *avctx)
static av_cold int sga_decode_end(AVCodecContext *avctx)
static int decode_index_tilemap(SGAVideoContext *s, AVFrame *frame)
static av_cold int sga_decode_init(AVCodecContext *avctx)
static int decode_index_palmap(SGAVideoContext *s, AVFrame *frame)
static int lzss_decompress(AVCodecContext *avctx, GetByteContext *gb, uint8_t *dst, int dst_size, int shift, int plus)
static int decode_palette(GetByteContext *gb, uint32_t *pal)
static int decode_index(SGAVideoContext *s, AVFrame *frame)
static int sga_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
static int decode_tiledata(AVCodecContext *avctx)
#define PALDATA_FOLLOWS_TILEDATA
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
typedef void(RENAME(mix_any_func_type))
static const uint8_t header[24]
static int shift(int a, int b)
main external API structure.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int width
picture width / height.
const char * name
Name of the codec implementation.
This structure describes decoded (raw) audio or video data.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int key_frame
1 -> keyframe, 0-> not
int palette_has_changed
Tell user application that palette has changed from previous frame.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
enum AVPictureType pict_type
Picture type of the frame.
This structure stores compressed data.
uint8_t uncompressed[65536]
unsigned palmapindex_size
uint8_t * palmapindex_data
static const uint8_t offset[127][2]