Fixes: Timeout Fixes: 11067/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_GDV_fuzzer-5686623711264768 Before change: Executed clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_GDV_fuzzer-5686623711264768 in 34386 ms After change: Executed clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_GDV_fuzzer-5686623711264768 in 24327 ms
Unified · Split
| @@ -72,9 +72,64 @@ static av_cold int gdv_decode_init(AVCodecContext *avctx) · 71 unmodified lines | |||
| 72 | return 0; | 72 | return 0; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | static void scaleup(uint8_t *dst, const uint8_t *src, int w) | ||
| 76 | { | ||
| 77 | int x; | ||
| 78 | for (x = 0; x < w - 7; x+=8) { | ||
| 79 | dst[x + 0] = | ||
| 80 | dst[x + 1] = src[(x>>1) + 0]; | ||
| 81 | dst[x + 2] = | ||
| 82 | dst[x + 3] = src[(x>>1) + 1]; | ||
| 83 | dst[x + 4] = | ||
| 84 | dst[x + 5] = src[(x>>1) + 2]; | ||
| 85 | dst[x + 6] = | ||
| 86 | dst[x + 7] = src[(x>>1) + 3]; | ||
| 87 | } | ||
| 88 | for (; x < w; x++) { | ||
| 89 | dst[x] = src[(x>>1)]; | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | static void scaleup_rev(uint8_t *dst, const uint8_t *src, int w) | ||
| 94 | { | ||
| 95 | int x; | ||
| 96 | |||
| 97 | for (x = w - 1; (x+1) & 7; x--) { | ||
| 98 | dst[x] = src[(x>>1)]; | ||
| 99 | } | ||
| 100 | for (x -= 7; x >= 0; x -= 8) { | ||
| 101 | dst[x + 6] = | ||
| 102 | dst[x + 7] = src[(x>>1) + 3]; | ||
| 103 | dst[x + 4] = | ||
| 104 | dst[x + 5] = src[(x>>1) + 2]; | ||
| 105 | dst[x + 2] = | ||
| 106 | dst[x + 3] = src[(x>>1) + 1]; | ||
| 107 | dst[x + 0] = | ||
| 108 | dst[x + 1] = src[(x>>1) + 0]; | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | static void scaledown(uint8_t *dst, const uint8_t *src, int w) | ||
| 113 | { | ||
| 114 | int x; | ||
| 115 | for (x = 0; x < w - 7; x+=8) { | ||
| 116 | dst[x + 0] = src[2*x + 0]; | ||
| 117 | dst[x + 1] = src[2*x + 2]; | ||
| 118 | dst[x + 2] = src[2*x + 4]; | ||
| 119 | dst[x + 3] = src[2*x + 6]; | ||
| 120 | dst[x + 4] = src[2*x + 8]; | ||
| 121 | dst[x + 5] = src[2*x +10]; | ||
| 122 | dst[x + 6] = src[2*x +12]; | ||
| 123 | dst[x + 7] = src[2*x +14]; | ||
| 124 | } | ||
| 125 | for (; x < w; x++) { | ||
| 126 | dst[x] = src[2*x]; | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 75 | static void rescale(GDVContext *gdv, uint8_t *dst, int w, int h, int scale_v, int scale_h) | 130 | static void rescale(GDVContext *gdv, uint8_t *dst, int w, int h, int scale_v, int scale_h) |
| 76 | { | 131 | { |
| 77 | int j, y, x; | 132 | int j, y; |
| 78 | 133 | ||
| 79 | if ((gdv->scale_v == scale_v) && (gdv->scale_h == scale_h)) { | 134 | if ((gdv->scale_v == scale_v) && (gdv->scale_h == scale_h)) { |
| 80 | return; | 135 | return; |
| @@ -86,14 +141,7 @@ static void rescale(GDVContext *gdv, uint8_t *dst, int w, int h, int scale_v, in · 5 unmodified lines | |||
| 86 | uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; | 141 | uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; |
| 87 | uint8_t *src1 = dst + PREAMBLE_SIZE + (y>>!!gdv->scale_h) * (w>>1); | 142 | uint8_t *src1 = dst + PREAMBLE_SIZE + (y>>!!gdv->scale_h) * (w>>1); |
| 88 | 143 | ||
| 89 | for (x = w - 1; x >= 0 && !(x&1); x--) { | 144 | scaleup_rev(dst1, src1, w); |
| 90 | dst1[x] = src1[(x>>1)]; | ||
| 91 | } | ||
| 92 | |||
| 93 | for (x--; x >= 0; x-=2) { | ||
| 94 | dst1[x ] = | ||
| 95 | dst1[x+1] = src1[(x>>1)]; | ||
| 96 | } | ||
| 97 | } | 145 | } |
| 98 | } else if (gdv->scale_h) { | 146 | } else if (gdv->scale_h) { |
| 99 | for (j = 0; j < h; j++) { | 147 | 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 · 8 unmodified lines | |||
| 108 | for (y = 0; y < (h>>1); y++) { | 156 | for (y = 0; y < (h>>1); y++) { |
| 109 | uint8_t *dst1 = dst + PREAMBLE_SIZE + y * (w>>1); | 157 | uint8_t *dst1 = dst + PREAMBLE_SIZE + y * (w>>1); |
| 110 | uint8_t *src1 = dst + PREAMBLE_SIZE + y*2 * w; | 158 | uint8_t *src1 = dst + PREAMBLE_SIZE + y*2 * w; |
| 111 | for (x = 0; x < (w>>1); x++) { | 159 | scaledown(dst1, src1, w>>1); |
| 112 | dst1[x] = src1[x*2]; | ||
| 113 | } | ||
| 114 | } | 160 | } |
| 115 | } else if (scale_h) { | 161 | } else if (scale_h) { |
| 116 | for (y = 0; y < (h>>1); y++) { | 162 | 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 · 4 unmodified lines | |||
| 121 | } else if (scale_v) { | 167 | } else if (scale_v) { |
| 122 | for (y = 0; y < h; y++) { | 168 | for (y = 0; y < h; y++) { |
| 123 | uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; | 169 | uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; |
| 124 | for (x = 0; x < (w>>1); x++) { | 170 | scaledown(dst1, dst1, w>>1); |
| 125 | dst1[x] = dst1[x*2]; | ||
| 126 | } | ||
| 127 | } | 171 | } |
| 128 | } | 172 | } |
| 129 | 173 | ||
| @@ -479,19 +523,16 @@ static int gdv_decode_frame(AVCodecContext *avctx, void *data, · 349 unmodified lines | |||
| 479 | } | 523 | } |
| 480 | } else { | 524 | } else { |
| 481 | int sidx = PREAMBLE_SIZE, didx = 0; | 525 | int sidx = PREAMBLE_SIZE, didx = 0; |
| 482 | int y, x; | 526 | int y; |
| 483 | 527 | ||
| 484 | for (y = 0; y < avctx->height; y++) { | 528 | for (y = 0; y < avctx->height; y++) { |
| 485 | if (!gdv->scale_v) { | 529 | if (!gdv->scale_v) { |
| 486 | memcpy(dst + didx, gdv->frame + sidx, avctx->width); | 530 | memcpy(dst + didx, gdv->frame + sidx, avctx->width); |
| 487 | } else { | 531 | } else { |
| 488 | for (x = 0; x < avctx->width - 1; x+=2) { | 532 | uint8_t *dst2 = dst + didx; |
| 489 | dst[didx + x ] = | 533 | uint8_t *src2 = gdv->frame + sidx; |
| 490 | dst[didx + x + 1] = gdv->frame[sidx + (x>>1)]; | 534 | |
| 491 | } | 535 | scaleup(dst2, src2, avctx->width); |
| 492 | for (; x < avctx->width; x++) { | ||
| 493 | dst[didx + x] = gdv->frame[sidx + (x>>1)]; | ||
| 494 | } | ||
| 495 | } | 536 | } |
| 496 | if (!gdv->scale_h || ((y & 1) == 1)) { | 537 | if (!gdv->scale_h || ((y & 1) == 1)) { |
| 497 | sidx += !gdv->scale_v ? avctx->width : avctx->width/2; | 538 | sidx += !gdv->scale_v ? avctx->width : avctx->width/2; |