|
|
|
@@ -72,9 +72,64 @@ static av_cold int gdv_decode_init(AVCodecContext *avctx) |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static void scaleup(uint8_t *dst, const uint8_t *src, int w) |
|
|
|
{ |
|
|
|
int x; |
|
|
|
for (x = 0; x < w - 7; x+=8) { |
|
|
|
dst[x + 0] = |
|
|
|
dst[x + 1] = src[(x>>1) + 0]; |
|
|
|
dst[x + 2] = |
|
|
|
dst[x + 3] = src[(x>>1) + 1]; |
|
|
|
dst[x + 4] = |
|
|
|
dst[x + 5] = src[(x>>1) + 2]; |
|
|
|
dst[x + 6] = |
|
|
|
dst[x + 7] = src[(x>>1) + 3]; |
|
|
|
} |
|
|
|
for (; x < w; x++) { |
|
|
|
dst[x] = src[(x>>1)]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void scaleup_rev(uint8_t *dst, const uint8_t *src, int w) |
|
|
|
{ |
|
|
|
int x; |
|
|
|
|
|
|
|
for (x = w - 1; (x+1) & 7; x--) { |
|
|
|
dst[x] = src[(x>>1)]; |
|
|
|
} |
|
|
|
for (x -= 7; x >= 0; x -= 8) { |
|
|
|
dst[x + 6] = |
|
|
|
dst[x + 7] = src[(x>>1) + 3]; |
|
|
|
dst[x + 4] = |
|
|
|
dst[x + 5] = src[(x>>1) + 2]; |
|
|
|
dst[x + 2] = |
|
|
|
dst[x + 3] = src[(x>>1) + 1]; |
|
|
|
dst[x + 0] = |
|
|
|
dst[x + 1] = src[(x>>1) + 0]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void scaledown(uint8_t *dst, const uint8_t *src, int w) |
|
|
|
{ |
|
|
|
int x; |
|
|
|
for (x = 0; x < w - 7; x+=8) { |
|
|
|
dst[x + 0] = src[2*x + 0]; |
|
|
|
dst[x + 1] = src[2*x + 2]; |
|
|
|
dst[x + 2] = src[2*x + 4]; |
|
|
|
dst[x + 3] = src[2*x + 6]; |
|
|
|
dst[x + 4] = src[2*x + 8]; |
|
|
|
dst[x + 5] = src[2*x +10]; |
|
|
|
dst[x + 6] = src[2*x +12]; |
|
|
|
dst[x + 7] = src[2*x +14]; |
|
|
|
} |
|
|
|
for (; x < w; x++) { |
|
|
|
dst[x] = src[2*x]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void rescale(GDVContext *gdv, uint8_t *dst, int w, int h, int scale_v, int scale_h) |
|
|
|
{ |
|
|
|
int j, y, x; |
|
|
|
int j, y; |
|
|
|
|
|
|
|
if ((gdv->scale_v == scale_v) && (gdv->scale_h == scale_h)) { |
|
|
|
return; |
|
|
|
@@ -86,14 +141,7 @@ static void rescale(GDVContext *gdv, uint8_t *dst, int w, int h, int scale_v, in |
|
|
|
uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; |
|
|
|
uint8_t *src1 = dst + PREAMBLE_SIZE + (y>>!!gdv->scale_h) * (w>>1); |
|
|
|
|
|
|
|
for (x = w - 1; x >= 0 && !(x&1); x--) { |
|
|
|
dst1[x] = src1[(x>>1)]; |
|
|
|
} |
|
|
|
|
|
|
|
for (x--; x >= 0; x-=2) { |
|
|
|
dst1[x ] = |
|
|
|
dst1[x+1] = src1[(x>>1)]; |
|
|
|
} |
|
|
|
scaleup_rev(dst1, src1, w); |
|
|
|
} |
|
|
|
} else if (gdv->scale_h) { |
|
|
|
for (j = 0; j < h; j++) { |
|
|
|
@@ -108,9 +156,7 @@ static void rescale(GDVContext *gdv, uint8_t *dst, int w, int h, int scale_v, in |
|
|
|
for (y = 0; y < (h>>1); y++) { |
|
|
|
uint8_t *dst1 = dst + PREAMBLE_SIZE + y * (w>>1); |
|
|
|
uint8_t *src1 = dst + PREAMBLE_SIZE + y*2 * w; |
|
|
|
for (x = 0; x < (w>>1); x++) { |
|
|
|
dst1[x] = src1[x*2]; |
|
|
|
} |
|
|
|
scaledown(dst1, src1, w>>1); |
|
|
|
} |
|
|
|
} else if (scale_h) { |
|
|
|
for (y = 0; y < (h>>1); y++) { |
|
|
|
@@ -121,9 +167,7 @@ static void rescale(GDVContext *gdv, uint8_t *dst, int w, int h, int scale_v, in |
|
|
|
} else if (scale_v) { |
|
|
|
for (y = 0; y < h; y++) { |
|
|
|
uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; |
|
|
|
for (x = 0; x < (w>>1); x++) { |
|
|
|
dst1[x] = dst1[x*2]; |
|
|
|
} |
|
|
|
scaledown(dst1, dst1, w>>1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@@ -481,19 +525,16 @@ static int gdv_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
} |
|
|
|
} else { |
|
|
|
int sidx = PREAMBLE_SIZE, didx = 0; |
|
|
|
int y, x; |
|
|
|
int y; |
|
|
|
|
|
|
|
for (y = 0; y < avctx->height; y++) { |
|
|
|
if (!gdv->scale_v) { |
|
|
|
memcpy(dst + didx, gdv->frame + sidx, avctx->width); |
|
|
|
} else { |
|
|
|
for (x = 0; x < avctx->width - 1; x+=2) { |
|
|
|
dst[didx + x ] = |
|
|
|
dst[didx + x + 1] = gdv->frame[sidx + (x>>1)]; |
|
|
|
} |
|
|
|
for (; x < avctx->width; x++) { |
|
|
|
dst[didx + x] = gdv->frame[sidx + (x>>1)]; |
|
|
|
} |
|
|
|
uint8_t *dst2 = dst + didx; |
|
|
|
uint8_t *src2 = gdv->frame + sidx; |
|
|
|
|
|
|
|
scaleup(dst2, src2, avctx->width); |
|
|
|
} |
|
|
|
if (!gdv->scale_h || ((y & 1) == 1)) { |
|
|
|
sidx += !gdv->scale_v ? avctx->width : avctx->width/2; |
|
|
|
|