29#define PALDATA_FOLLOWS_TILEDATA 4
30#define HAVE_COMPRESSED_TILEMAP 32
31#define HAVE_TILEMAP 128
75 memset(pal, 0, 16 *
sizeof(*pal));
78 for (
int RGBIndex = 0; RGBIndex < 3; RGBIndex++) {
85 for (
int RGBIndex = 0; RGBIndex < 3; RGBIndex++) {
92 for (
int RGBIndex = 0; RGBIndex < 3; RGBIndex++) {
109 const uint8_t *tt =
s->tileindex_data;
111 for (
int y = 0; y <
s->tiles_h; y++) {
112 for (
int x = 0; x <
s->tiles_w; x++) {
113 int pal_idx =
s->palmapindex_data[y *
s->tiles_w + x] * 16;
114 uint8_t *
dst =
frame->data[0] + y * 8 *
frame->linesize[0] + x * 8;
116 for (
int yy = 0; yy < 8; yy++) {
117 for (
int xx = 0; xx < 8; xx++)
118 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++) {
142 int tilemap = bytestream2_get_be16u(&gb2);
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;
148 uint8_t *
dst =
frame->data[0] + y * 8 *
frame->linesize[0] + x * 8;
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];
183 const uint8_t *
src =
s->tileindex_data;
186 for (
int y = 0; y <
frame->height; y += 8) {
187 for (
int x = 0; x <
frame->width; x += 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++) {
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)
320 if (avpkt->
size <= 14)
323 s->flags = avpkt->
data[8];
324 s->nb_pal = avpkt->
data[9];
325 s->tiles_w = avpkt->
data[10];
326 s->tiles_h = avpkt->
data[11];
333 s->tiles_h * 8)) < 0)
338 if (!
s->tileindex_data)
342 s->tiles_w *
s->tiles_h);
343 if (!
s->palmapindex_data)
351 type = bytestream2_get_byte(gb);
354 if (
s->nb_tiles >
s->tiles_w *
s->tiles_h)
395 for (
int i = 0;
i < 3;
i++)
396 sizes[
i] = bytestream2_get_be16(gb);
398 for (
int i = 0;
i < 3;
i++) {
400 int raw =
size >> 15;
402 size &= (1 << 15) - 1;
421 sizeof(
s->uncompressed) -
offset,
s->shift,
s->plus);
450 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) {
518 s->tileindex_size = 0;
521 s->palmapindex_size = 0;
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
const FFCodec ff_sga_decoder
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Libavcodec external API header.
static int BS_FUNC left(const BSCTX *bc)
Return the number of the bits left in a buffer.
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(const 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)
static int FUNC tile(CodedBitstreamContext *ctx, RWContext *rw, APVRawTile *current, int tile_idx, uint32_t tile_size)
#define i(width, name, range_min, range_max)
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
common internal and external API header
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
int ff_set_dimensions(AVCodecContext *s, int width, int height)
int(* init)(AVBSFContext *ctx)
static const uint8_t bits[8]
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_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
#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]
static int shift(int a, int b)
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 sga_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
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 decode_tiledata(AVCodecContext *avctx)
#define PALDATA_FOLLOWS_TILEDATA
#define FFSWAP(type, a, b)
Memory handling functions.
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
static const uint8_t header[24]
main external API structure.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int width
picture width / height.
This structure describes decoded (raw) audio or video data.
This structure stores compressed data.
uint8_t uncompressed[65536]
unsigned palmapindex_size
uint8_t * palmapindex_data