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 | 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 | 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 | 134 | if ((gdv->scale_v == scale_v) && (gdv->scale_h == scale_h)) { |
| 80 | 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 | 141 | uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; |
| 87 | 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--) { | |
| 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 | − } | |
| 144 | + scaleup_rev(dst1, src1, w); | |
| 97 | 145 | } |
| 98 | 146 | } else if (gdv->scale_h) { |
| 99 | 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 | 156 | for (y = 0; y < (h>>1); y++) { |
| 109 | 157 | uint8_t *dst1 = dst + PREAMBLE_SIZE + y * (w>>1); |
| 110 | 158 | uint8_t *src1 = dst + PREAMBLE_SIZE + y*2 * w; |
| 111 | − for (x = 0; x < (w>>1); x++) { | |
| 112 | − dst1[x] = src1[x*2]; | |
| 113 | − } | |
| 159 | + scaledown(dst1, src1, w>>1); | |
| 114 | 160 | } |
| 115 | 161 | } else if (scale_h) { |
| 116 | 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 | 167 | } else if (scale_v) { |
| 122 | 168 | for (y = 0; y < h; y++) { |
| 123 | 169 | uint8_t *dst1 = dst + PREAMBLE_SIZE + y * w; |
| 124 | − for (x = 0; x < (w>>1); x++) { | |
| 125 | − dst1[x] = dst1[x*2]; | |
| 126 | − } | |
| 170 | + scaledown(dst1, dst1, w>>1); | |
| 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 | 524 | } else { |
| 481 | 525 | int sidx = PREAMBLE_SIZE, didx = 0; |
| 482 | − int y, x; | |
| 526 | + int y; | |
| 483 | 527 | |
| 484 | 528 | for (y = 0; y < avctx->height; y++) { |
| 485 | 529 | if (!gdv->scale_v) { |
| 486 | 530 | memcpy(dst + didx, gdv->frame + sidx, avctx->width); |
| 487 | 531 | } else { |
| 488 | − for (x = 0; x < avctx->width - 1; x+=2) { | |
| 489 | − dst[didx + x ] = | |
| 490 | − dst[didx + x + 1] = gdv->frame[sidx + (x>>1)]; | |
| 491 | − } | |
| 492 | − for (; x < avctx->width; x++) { | |
| 493 | − dst[didx + x] = gdv->frame[sidx + (x>>1)]; | |
| 494 | − } | |
| 532 | + uint8_t *dst2 = dst + didx; | |
| 533 | + uint8_t *src2 = gdv->frame + sidx; | |
| 534 | + | |
| 535 | + scaleup(dst2, src2, avctx->width); | |
| 495 | 536 | } |
| 496 | 537 | if (!gdv->scale_h || ((y & 1) == 1)) { |
| 497 | 538 | sidx += !gdv->scale_v ? avctx->width : avctx->width/2; |