mirror of https://github.com/FFmpeg/FFmpeg.git
parent
80ce23da65
commit
a064530da8
4 changed files with 1696 additions and 308 deletions
@ -0,0 +1,349 @@ |
||||
/*
|
||||
* ScreenPressor decoder |
||||
* |
||||
* Copyright (c) 2017 Paul B Mahol |
||||
* |
||||
* This file is part of FFmpeg. |
||||
* |
||||
* FFmpeg is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* FFmpeg is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with FFmpeg; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#ifndef AVCODEC_SCPR_H |
||||
#define AVCODEC_SCPR_H |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include "avcodec.h" |
||||
#include "bytestream.h" |
||||
#include "internal.h" |
||||
#include "scpr3.h" |
||||
|
||||
typedef struct RangeCoder { |
||||
uint32_t code; |
||||
uint32_t range; |
||||
uint32_t code1; |
||||
} RangeCoder; |
||||
|
||||
typedef struct PixelModel { |
||||
uint32_t freq[256]; |
||||
uint32_t lookup[16]; |
||||
uint32_t total_freq; |
||||
} PixelModel; |
||||
|
||||
typedef struct SCPRContext { |
||||
int version; |
||||
AVFrame *last_frame; |
||||
AVFrame *current_frame; |
||||
GetByteContext gb; |
||||
RangeCoder rc; |
||||
PixelModel pixel_model[3][4096]; |
||||
uint32_t op_model[6][7]; |
||||
uint32_t run_model[6][257]; |
||||
uint32_t range_model[257]; |
||||
uint32_t count_model[257]; |
||||
uint32_t fill_model[6]; |
||||
uint32_t sxy_model[4][17]; |
||||
uint32_t mv_model[2][513]; |
||||
uint32_t nbx, nby; |
||||
uint32_t nbcount; |
||||
uint32_t *blocks; |
||||
uint32_t cbits; |
||||
int cxshift; |
||||
|
||||
PixelModel3 pixel_model3[3][4096]; |
||||
RunModel3 run_model3[6]; |
||||
RunModel3 range_model3; |
||||
RunModel3 count_model3; |
||||
FillModel3 fill_model3; |
||||
SxyModel3 sxy_model3[4]; |
||||
MVModel3 mv_model3[2]; |
||||
OpModel3 op_model3[6]; |
||||
|
||||
int (*get_freq)(RangeCoder *rc, uint32_t total_freq, uint32_t *freq); |
||||
int (*decode)(GetByteContext *gb, RangeCoder *rc, uint32_t cumFreq, uint32_t freq, uint32_t total_freq); |
||||
} SCPRContext; |
||||
|
||||
static int decode_run_i(AVCodecContext *avctx, uint32_t ptype, int run, |
||||
int *x, int *y, uint32_t clr, uint32_t *dst, |
||||
int linesize, uint32_t *lx, uint32_t *ly, |
||||
uint32_t backstep, int off, int *cx, int *cx1) |
||||
{ |
||||
uint32_t r, g, b; |
||||
int z; |
||||
|
||||
switch (ptype) { |
||||
case 0: |
||||
while (run-- > 0) { |
||||
if (*y >= avctx->height) |
||||
return AVERROR_INVALIDDATA; |
||||
|
||||
dst[*y * linesize + *x] = clr; |
||||
*lx = *x; |
||||
*ly = *y; |
||||
(*x)++; |
||||
if (*x >= avctx->width) { |
||||
*x = 0; |
||||
(*y)++; |
||||
} |
||||
} |
||||
break; |
||||
case 1: |
||||
while (run-- > 0) { |
||||
if (*y >= avctx->height) |
||||
return AVERROR_INVALIDDATA; |
||||
|
||||
dst[*y * linesize + *x] = dst[*ly * linesize + *lx]; |
||||
*lx = *x; |
||||
*ly = *y; |
||||
(*x)++; |
||||
if (*x >= avctx->width) { |
||||
*x = 0; |
||||
(*y)++; |
||||
} |
||||
} |
||||
clr = dst[*ly * linesize + *lx]; |
||||
break; |
||||
case 2: |
||||
while (run-- > 0) { |
||||
if (*y < 1 || *y >= avctx->height) |
||||
return AVERROR_INVALIDDATA; |
||||
|
||||
clr = dst[*y * linesize + *x + off + 1]; |
||||
dst[*y * linesize + *x] = clr; |
||||
*lx = *x; |
||||
*ly = *y; |
||||
(*x)++; |
||||
if (*x >= avctx->width) { |
||||
*x = 0; |
||||
(*y)++; |
||||
} |
||||
} |
||||
break; |
||||
case 4: |
||||
while (run-- > 0) { |
||||
uint8_t *odst = (uint8_t *)dst; |
||||
|
||||
if (*y < 1 || *y >= avctx->height || |
||||
(*y == 1 && *x == 0)) |
||||
return AVERROR_INVALIDDATA; |
||||
|
||||
if (*x == 0) { |
||||
z = backstep; |
||||
} else { |
||||
z = 0; |
||||
} |
||||
|
||||
r = odst[(*ly * linesize + *lx) * 4] + |
||||
odst[((*y * linesize + *x) + off) * 4 + 4] - |
||||
odst[((*y * linesize + *x) + off - z) * 4]; |
||||
g = odst[(*ly * linesize + *lx) * 4 + 1] + |
||||
odst[((*y * linesize + *x) + off) * 4 + 5] - |
||||
odst[((*y * linesize + *x) + off - z) * 4 + 1]; |
||||
b = odst[(*ly * linesize + *lx) * 4 + 2] + |
||||
odst[((*y * linesize + *x) + off) * 4 + 6] - |
||||
odst[((*y * linesize + *x) + off - z) * 4 + 2]; |
||||
clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF); |
||||
dst[*y * linesize + *x] = clr; |
||||
*lx = *x; |
||||
*ly = *y; |
||||
(*x)++; |
||||
if (*x >= avctx->width) { |
||||
*x = 0; |
||||
(*y)++; |
||||
} |
||||
} |
||||
break; |
||||
case 5: |
||||
while (run-- > 0) { |
||||
if (*y < 1 || *y >= avctx->height || |
||||
(*y == 1 && *x == 0)) |
||||
return AVERROR_INVALIDDATA; |
||||
|
||||
if (*x == 0) { |
||||
z = backstep; |
||||
} else { |
||||
z = 0; |
||||
} |
||||
|
||||
clr = dst[*y * linesize + *x + off - z]; |
||||
dst[*y * linesize + *x] = clr; |
||||
*lx = *x; |
||||
*ly = *y; |
||||
(*x)++; |
||||
if (*x >= avctx->width) { |
||||
*x = 0; |
||||
(*y)++; |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
|
||||
if (avctx->bits_per_coded_sample == 16) { |
||||
*cx1 = (clr & 0x3F00) >> 2; |
||||
*cx = (clr & 0x3FFFFF) >> 16; |
||||
} else { |
||||
*cx1 = (clr & 0xFC00) >> 4; |
||||
*cx = (clr & 0xFFFFFF) >> 18; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int decode_run_p(AVCodecContext *avctx, uint32_t ptype, int run, |
||||
int x, int y, uint32_t clr, |
||||
uint32_t *dst, uint32_t *prev, |
||||
int linesize, int plinesize, |
||||
uint32_t *bx, uint32_t *by, |
||||
uint32_t backstep, int sx1, int sx2, |
||||
int *cx, int *cx1) |
||||
{ |
||||
uint32_t r, g, b; |
||||
int z; |
||||
|
||||
switch (ptype) { |
||||
case 0: |
||||
while (run-- > 0) { |
||||
if (*by >= avctx->height) |
||||
return AVERROR_INVALIDDATA; |
||||
|
||||
dst[*by * linesize + *bx] = clr; |
||||
(*bx)++; |
||||
if (*bx >= x * 16 + sx2 || *bx >= avctx->width) { |
||||
*bx = x * 16 + sx1; |
||||
(*by)++; |
||||
} |
||||
} |
||||
break; |
||||
case 1: |
||||
while (run-- > 0) { |
||||
if (*bx == 0) { |
||||
if (*by < 1) |
||||
return AVERROR_INVALIDDATA; |
||||
z = backstep; |
||||
} else { |
||||
z = 0; |
||||
} |
||||
|
||||
if (*by >= avctx->height) |
||||
return AVERROR_INVALIDDATA; |
||||
|
||||
clr = dst[*by * linesize + *bx - 1 - z]; |
||||
dst[*by * linesize + *bx] = clr; |
||||
(*bx)++; |
||||
if (*bx >= x * 16 + sx2 || *bx >= avctx->width) { |
||||
*bx = x * 16 + sx1; |
||||
(*by)++; |
||||
} |
||||
} |
||||
break; |
||||
case 2: |
||||
while (run-- > 0) { |
||||
if (*by < 1 || *by >= avctx->height) |
||||
return AVERROR_INVALIDDATA; |
||||
|
||||
clr = dst[(*by - 1) * linesize + *bx]; |
||||
dst[*by * linesize + *bx] = clr; |
||||
(*bx)++; |
||||
if (*bx >= x * 16 + sx2 || *bx >= avctx->width) { |
||||
*bx = x * 16 + sx1; |
||||
(*by)++; |
||||
} |
||||
} |
||||
break; |
||||
case 3: |
||||
while (run-- > 0) { |
||||
if (*by >= avctx->height) |
||||
return AVERROR_INVALIDDATA; |
||||
|
||||
clr = prev[*by * plinesize + *bx]; |
||||
dst[*by * linesize + *bx] = clr; |
||||
(*bx)++; |
||||
if (*bx >= x * 16 + sx2 || *bx >= avctx->width) { |
||||
*bx = x * 16 + sx1; |
||||
(*by)++; |
||||
} |
||||
} |
||||
break; |
||||
case 4: |
||||
while (run-- > 0) { |
||||
uint8_t *odst = (uint8_t *)dst; |
||||
|
||||
if (*by < 1 || *by >= avctx->height) |
||||
return AVERROR_INVALIDDATA; |
||||
|
||||
if (*bx == 0) { |
||||
if (*by < 2) |
||||
return AVERROR_INVALIDDATA; |
||||
z = backstep; |
||||
} else { |
||||
z = 0; |
||||
} |
||||
|
||||
r = odst[((*by - 1) * linesize + *bx) * 4] + |
||||
odst[(*by * linesize + *bx - 1 - z) * 4] - |
||||
odst[((*by - 1) * linesize + *bx - 1 - z) * 4]; |
||||
g = odst[((*by - 1) * linesize + *bx) * 4 + 1] + |
||||
odst[(*by * linesize + *bx - 1 - z) * 4 + 1] - |
||||
odst[((*by - 1) * linesize + *bx - 1 - z) * 4 + 1]; |
||||
b = odst[((*by - 1) * linesize + *bx) * 4 + 2] + |
||||
odst[(*by * linesize + *bx - 1 - z) * 4 + 2] - |
||||
odst[((*by - 1) * linesize + *bx - 1 - z) * 4 + 2]; |
||||
clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF); |
||||
dst[*by * linesize + *bx] = clr; |
||||
(*bx)++; |
||||
if (*bx >= x * 16 + sx2 || *bx >= avctx->width) { |
||||
*bx = x * 16 + sx1; |
||||
(*by)++; |
||||
} |
||||
} |
||||
break; |
||||
case 5: |
||||
while (run-- > 0) { |
||||
if (*by < 1 || *by >= avctx->height) |
||||
return AVERROR_INVALIDDATA; |
||||
|
||||
if (*bx == 0) { |
||||
if (*by < 2) |
||||
return AVERROR_INVALIDDATA; |
||||
z = backstep; |
||||
} else { |
||||
z = 0; |
||||
} |
||||
|
||||
clr = dst[(*by - 1) * linesize + *bx - 1 - z]; |
||||
dst[*by * linesize + *bx] = clr; |
||||
(*bx)++; |
||||
if (*bx >= x * 16 + sx2 || *bx >= avctx->width) { |
||||
*bx = x * 16 + sx1; |
||||
(*by)++; |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
|
||||
if (avctx->bits_per_coded_sample == 16) { |
||||
*cx1 = (clr & 0x3F00) >> 2; |
||||
*cx = (clr & 0x3FFFFF) >> 16; |
||||
} else { |
||||
*cx1 = (clr & 0xFC00) >> 4; |
||||
*cx = (clr & 0xFFFFFF) >> 18; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
#endif /* AVCODEC_SCPR_H */ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,82 @@ |
||||
/*
|
||||
* ScreenPressor version 3 decoder |
||||
* |
||||
* Copyright (c) 2017 Paul B Mahol |
||||
* |
||||
* This file is part of FFmpeg. |
||||
* |
||||
* FFmpeg is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* FFmpeg is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with FFmpeg; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#ifndef AVCODEC_SCPR3_H |
||||
#define AVCODEC_SCPR3_H |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include "avcodec.h" |
||||
#include "internal.h" |
||||
|
||||
typedef struct PixelModel3 { |
||||
uint8_t type; |
||||
uint8_t length; |
||||
uint8_t maxpos; |
||||
uint8_t fshift; |
||||
uint16_t size; |
||||
uint32_t cntsum; |
||||
uint8_t symbols[256]; |
||||
uint16_t freqs[256]; |
||||
uint16_t freqs1[256]; |
||||
uint16_t cnts[256]; |
||||
uint8_t dectab[32]; |
||||
} PixelModel3; |
||||
|
||||
typedef struct FillModel3 { |
||||
uint32_t cntsum; |
||||
uint16_t freqs[2][5]; |
||||
uint16_t cnts[5]; |
||||
uint8_t dectab[32]; |
||||
} FillModel3; |
||||
|
||||
typedef struct OpModel3 { |
||||
uint32_t cntsum; |
||||
uint16_t freqs[2][6]; |
||||
uint16_t cnts[6]; |
||||
uint8_t dectab[32]; |
||||
} OpModel3; |
||||
|
||||
typedef struct RunModel3 { |
||||
uint32_t cntsum; |
||||
uint16_t freqs[2][256]; |
||||
uint16_t cnts[256]; |
||||
uint8_t dectab[32]; |
||||
} RunModel3; |
||||
|
||||
typedef struct SxyModel3 { |
||||
uint32_t cntsum; |
||||
uint16_t freqs[2][16]; |
||||
uint16_t cnts[16]; |
||||
uint8_t dectab[32]; |
||||
} SxyModel3; |
||||
|
||||
typedef struct MVModel3 { |
||||
uint32_t cntsum; |
||||
uint16_t freqs[2][512]; |
||||
uint16_t cnts[512]; |
||||
uint8_t dectab[32]; |
||||
} MVModel3; |
||||
|
||||
#endif /* AVCODEC_SCPR3_H */ |
Loading…
Reference in new issue