| 87 | } |
| 88 | |
| 89 | static int gem_decode_frame(AVCodecContext *avctx, AVFrame *p, |
| 90 | int *got_frame, AVPacket *avpkt) |
| 91 | { |
| 92 | const uint8_t *buf = avpkt->data; |
| 93 | int buf_size = avpkt->size; |
| 94 | const uint8_t *buf_end = buf + buf_size; |
| 95 | int header_size, planes, pattern_size, tag = 0, count_scalar = 1, ret; |
| 96 | unsigned int x, count, v; |
| 97 | GetByteContext gb; |
| 98 | uint32_t *palette; |
| 99 | const uint8_t * b; |
| 100 | uint8_t * row; |
| 101 | int row_width, pixel_size; |
| 102 | State state = {.y = 0, .pl = 0, .x = 0, .vdup = 1}; |
| 103 | void (*put_lines)(AVCodecContext *avctx, int planes, int row_width, int pixel_size, State * state, uint8_t * row, AVFrame *p); |
| 104 | int width, height; |
| 105 | |
| 106 | if (buf_size <= 16) |
| 107 | return AVERROR_INVALIDDATA; |
| 108 | |
| 109 | bytestream2_init(&gb, buf + 2, buf_size - 2); |
| 110 | header_size = bytestream2_get_be16(&gb); |
| 111 | if (header_size < 8 || buf_size <= header_size * 2) |
| 112 | return AVERROR_INVALIDDATA; |
| 113 | |
| 114 | planes = bytestream2_get_be16(&gb); |
| 115 | pattern_size = bytestream2_get_be16(&gb); |
| 116 | avctx->sample_aspect_ratio.num = bytestream2_get_be16(&gb); |
| 117 | avctx->sample_aspect_ratio.den = bytestream2_get_be16(&gb); |
| 118 | width = bytestream2_get_be16(&gb); |
| 119 | height = bytestream2_get_be16(&gb); |
| 120 | ret = ff_set_dimensions(avctx, width, height); |
| 121 | if (ret < 0) |
| 122 | return ret; |
| 123 | |
| 124 | row_width = (avctx->width + 7) / 8; |
| 125 | put_lines = put_lines_bits; |
| 126 | |
| 127 | if (header_size == 9) { |
| 128 | count_scalar = bytestream2_get_be16(&gb); |
| 129 | if (count_scalar != 3) { |
| 130 | avpriv_request_sample(avctx, "count_scalar=%d", count_scalar); |
| 131 | return AVERROR_PATCHWELCOME; |
| 132 | } |
| 133 | planes = 24; |
| 134 | avctx->pix_fmt = AV_PIX_FMT_BGR24; |
| 135 | pixel_size = 3; |
| 136 | } else if (planes == 15) { |
| 137 | #if HAVE_BIGENDIAN |
| 138 | avctx->pix_fmt = AV_PIX_FMT_BGR555BE; |
| 139 | #else |
| 140 | avctx->pix_fmt = AV_PIX_FMT_BGR555LE; |
| 141 | #endif |
| 142 | pixel_size = 2; |
| 143 | } else if (planes == 16) { |
| 144 | avctx->pix_fmt = AV_PIX_FMT_RGB565BE; |
| 145 | pixel_size = 2; |
| 146 | } else if (planes == 24) { |
nothing calls this directly
no test coverage detected