* qatar/master: FATE: add tests for targa ARM: fix Thumb-mode simple_idct_arm ARM: 4-byte align start of all asm functions rgb2rgb: rgb12to15() swscale-test: fix stack overread. swscale: fix invalid conversions and memory problems. cabac: split cabac.h into declarations and function definitions cabac: Mark ff_h264_mps_state array as static, it is only used within cabac.c. cabac: Remove ff_h264_lps_state array. Conflicts: libswscale/rgb2rgb.h libswscale/swscale_unscaled.c tests/fate/image.mak Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n0.10
| @@ -68,6 +68,7 @@ ELF .size \name, . - \name | |||||
| .purgem endfunc | .purgem endfunc | ||||
| .endm | .endm | ||||
| .text | .text | ||||
| .align 2 | |||||
| .if \export | .if \export | ||||
| .global EXTERN_ASM\name | .global EXTERN_ASM\name | ||||
| EXTERN_ASM\name: | EXTERN_ASM\name: | ||||
| @@ -491,8 +491,8 @@ __end_bef_a_evaluation: | |||||
| bal __end_a_evaluation | bal __end_a_evaluation | ||||
| __constant_ptr__: @@ see #defines at the beginning of the source code for values. | |||||
| .align | .align | ||||
| __constant_ptr__: @@ see #defines at the beginning of the source code for values. | |||||
| .word W1 | .word W1 | ||||
| .word W2 | .word W2 | ||||
| .word W3 | .word W3 | ||||
| @@ -29,6 +29,7 @@ | |||||
| #include "libavutil/common.h" | #include "libavutil/common.h" | ||||
| #include "get_bits.h" | #include "get_bits.h" | ||||
| #include "cabac.h" | #include "cabac.h" | ||||
| #include "cabac_functions.h" | |||||
| static const uint8_t lps_range[64][4]= { | static const uint8_t lps_range[64][4]= { | ||||
| {128,176,208,240}, {128,167,197,227}, {128,158,187,216}, {123,150,178,205}, | {128,176,208,240}, {128,167,197,227}, {128,158,187,216}, {123,150,178,205}, | ||||
| @@ -51,8 +52,7 @@ static const uint8_t lps_range[64][4]= { | |||||
| uint8_t ff_h264_mlps_state[4*64]; | uint8_t ff_h264_mlps_state[4*64]; | ||||
| uint8_t ff_h264_lps_range[4*2*64]; | uint8_t ff_h264_lps_range[4*2*64]; | ||||
| uint8_t ff_h264_lps_state[2*64]; | |||||
| uint8_t ff_h264_mps_state[2*64]; | |||||
| static uint8_t h264_mps_state[2 * 64]; | |||||
| static const uint8_t mps_state[64]= { | static const uint8_t mps_state[64]= { | ||||
| 1, 2, 3, 4, 5, 6, 7, 8, | 1, 2, 3, 4, 5, 6, 7, 8, | ||||
| @@ -141,9 +141,9 @@ void ff_init_cabac_states(CABACContext *c){ | |||||
| } | } | ||||
| ff_h264_mlps_state[128+2*i+0]= | ff_h264_mlps_state[128+2*i+0]= | ||||
| ff_h264_mps_state[2*i+0]= 2*mps_state[i]+0; | |||||
| h264_mps_state[2 * i + 0] = 2 * mps_state[i] + 0; | |||||
| ff_h264_mlps_state[128+2*i+1]= | ff_h264_mlps_state[128+2*i+1]= | ||||
| ff_h264_mps_state[2*i+1]= 2*mps_state[i]+1; | |||||
| h264_mps_state[2 * i + 1] = 2 * mps_state[i] + 1; | |||||
| if( i ){ | if( i ){ | ||||
| ff_h264_lps_state[2*i+0]= | ff_h264_lps_state[2*i+0]= | ||||
| @@ -196,11 +196,10 @@ static void put_cabac(CABACContext *c, uint8_t * const state, int bit){ | |||||
| if(bit == ((*state)&1)){ | if(bit == ((*state)&1)){ | ||||
| c->range -= RangeLPS; | c->range -= RangeLPS; | ||||
| *state= ff_h264_mps_state[*state]; | |||||
| *state = h264_mps_state[*state]; | |||||
| }else{ | }else{ | ||||
| c->low += c->range - RangeLPS; | c->low += c->range - RangeLPS; | ||||
| c->range = RangeLPS; | c->range = RangeLPS; | ||||
| *state= ff_h264_lps_state[*state]; | |||||
| } | } | ||||
| renorm_cabac_encoder(c); | renorm_cabac_encoder(c); | ||||
| @@ -27,13 +27,10 @@ | |||||
| #ifndef AVCODEC_CABAC_H | #ifndef AVCODEC_CABAC_H | ||||
| #define AVCODEC_CABAC_H | #define AVCODEC_CABAC_H | ||||
| #include <stddef.h> | |||||
| #include <stdint.h> | |||||
| #include "put_bits.h" | #include "put_bits.h" | ||||
| //#undef NDEBUG | |||||
| #include <assert.h> | |||||
| #define CABAC_BITS 16 | #define CABAC_BITS 16 | ||||
| #define CABAC_MASK ((1<<CABAC_BITS)-1) | #define CABAC_MASK ((1<<CABAC_BITS)-1) | ||||
| @@ -47,136 +44,8 @@ typedef struct CABACContext{ | |||||
| PutBitContext pb; | PutBitContext pb; | ||||
| }CABACContext; | }CABACContext; | ||||
| extern uint8_t ff_h264_mlps_state[4*64]; | |||||
| extern uint8_t ff_h264_lps_range[4*2*64]; ///< rangeTabLPS | |||||
| extern uint8_t ff_h264_mps_state[2*64]; ///< transIdxMPS | |||||
| extern uint8_t ff_h264_lps_state[2*64]; ///< transIdxLPS | |||||
| extern const uint8_t ff_h264_norm_shift[512]; | |||||
| #if ARCH_X86 | |||||
| # include "x86/cabac.h" | |||||
| #endif | |||||
| void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size); | void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size); | ||||
| void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size); | void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size); | ||||
| void ff_init_cabac_states(CABACContext *c); | void ff_init_cabac_states(CABACContext *c); | ||||
| static void refill(CABACContext *c){ | |||||
| #if CABAC_BITS == 16 | |||||
| c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); | |||||
| #else | |||||
| c->low+= c->bytestream[0]<<1; | |||||
| #endif | |||||
| c->low -= CABAC_MASK; | |||||
| c->bytestream+= CABAC_BITS/8; | |||||
| } | |||||
| static inline void renorm_cabac_decoder_once(CABACContext *c){ | |||||
| int shift= (uint32_t)(c->range - 0x100)>>31; | |||||
| c->range<<= shift; | |||||
| c->low <<= shift; | |||||
| if(!(c->low & CABAC_MASK)) | |||||
| refill(c); | |||||
| } | |||||
| #ifndef get_cabac_inline | |||||
| static void refill2(CABACContext *c){ | |||||
| int i, x; | |||||
| x= c->low ^ (c->low-1); | |||||
| i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; | |||||
| x= -CABAC_MASK; | |||||
| #if CABAC_BITS == 16 | |||||
| x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); | |||||
| #else | |||||
| x+= c->bytestream[0]<<1; | |||||
| #endif | |||||
| c->low += x<<i; | |||||
| c->bytestream+= CABAC_BITS/8; | |||||
| } | |||||
| static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ | |||||
| int s = *state; | |||||
| int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; | |||||
| int bit, lps_mask; | |||||
| c->range -= RangeLPS; | |||||
| lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; | |||||
| c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; | |||||
| c->range += (RangeLPS - c->range) & lps_mask; | |||||
| s^=lps_mask; | |||||
| *state= (ff_h264_mlps_state+128)[s]; | |||||
| bit= s&1; | |||||
| lps_mask= ff_h264_norm_shift[c->range]; | |||||
| c->range<<= lps_mask; | |||||
| c->low <<= lps_mask; | |||||
| if(!(c->low & CABAC_MASK)) | |||||
| refill2(c); | |||||
| return bit; | |||||
| } | |||||
| #endif | |||||
| static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){ | |||||
| return get_cabac_inline(c,state); | |||||
| } | |||||
| static int av_unused get_cabac(CABACContext *c, uint8_t * const state){ | |||||
| return get_cabac_inline(c,state); | |||||
| } | |||||
| static int av_unused get_cabac_bypass(CABACContext *c){ | |||||
| int range; | |||||
| c->low += c->low; | |||||
| if(!(c->low & CABAC_MASK)) | |||||
| refill(c); | |||||
| range= c->range<<(CABAC_BITS+1); | |||||
| if(c->low < range){ | |||||
| return 0; | |||||
| }else{ | |||||
| c->low -= range; | |||||
| return 1; | |||||
| } | |||||
| } | |||||
| #ifndef get_cabac_bypass_sign | |||||
| static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ | |||||
| int range, mask; | |||||
| c->low += c->low; | |||||
| if(!(c->low & CABAC_MASK)) | |||||
| refill(c); | |||||
| range= c->range<<(CABAC_BITS+1); | |||||
| c->low -= range; | |||||
| mask= c->low >> 31; | |||||
| range &= mask; | |||||
| c->low += range; | |||||
| return (val^mask)-mask; | |||||
| } | |||||
| #endif | |||||
| /** | |||||
| * | |||||
| * @return the number of bytes read or 0 if no end | |||||
| */ | |||||
| static int av_unused get_cabac_terminate(CABACContext *c){ | |||||
| c->range -= 2; | |||||
| if(c->low < c->range<<(CABAC_BITS+1)){ | |||||
| renorm_cabac_decoder_once(c); | |||||
| return 0; | |||||
| }else{ | |||||
| return c->bytestream - c->bytestream_start; | |||||
| } | |||||
| } | |||||
| #endif /* AVCODEC_CABAC_H */ | #endif /* AVCODEC_CABAC_H */ | ||||
| @@ -0,0 +1,160 @@ | |||||
| /* | |||||
| * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder | |||||
| * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> | |||||
| * | |||||
| * This file is part of Libav. | |||||
| * | |||||
| * Libav 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. | |||||
| * | |||||
| * Libav 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 Libav; if not, write to the Free Software | |||||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||||
| */ | |||||
| /** | |||||
| * @file | |||||
| * Context Adaptive Binary Arithmetic Coder inline functions | |||||
| */ | |||||
| #ifndef AVCODEC_CABAC_FUNCTIONS_H | |||||
| #define AVCODEC_CABAC_FUNCTIONS_H | |||||
| #include <stdint.h> | |||||
| #include "cabac.h" | |||||
| #include "config.h" | |||||
| #if ARCH_X86 | |||||
| # include "x86/cabac.h" | |||||
| #endif | |||||
| extern const uint8_t ff_h264_norm_shift[512]; | |||||
| extern uint8_t ff_h264_mlps_state[4*64]; | |||||
| extern uint8_t ff_h264_lps_range[4*2*64]; ///< rangeTabLPS | |||||
| static void refill(CABACContext *c){ | |||||
| #if CABAC_BITS == 16 | |||||
| c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); | |||||
| #else | |||||
| c->low+= c->bytestream[0]<<1; | |||||
| #endif | |||||
| c->low -= CABAC_MASK; | |||||
| c->bytestream+= CABAC_BITS/8; | |||||
| } | |||||
| static inline void renorm_cabac_decoder_once(CABACContext *c){ | |||||
| int shift= (uint32_t)(c->range - 0x100)>>31; | |||||
| c->range<<= shift; | |||||
| c->low <<= shift; | |||||
| if(!(c->low & CABAC_MASK)) | |||||
| refill(c); | |||||
| } | |||||
| #ifndef get_cabac_inline | |||||
| static void refill2(CABACContext *c){ | |||||
| int i, x; | |||||
| x= c->low ^ (c->low-1); | |||||
| i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; | |||||
| x= -CABAC_MASK; | |||||
| #if CABAC_BITS == 16 | |||||
| x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); | |||||
| #else | |||||
| x+= c->bytestream[0]<<1; | |||||
| #endif | |||||
| c->low += x<<i; | |||||
| c->bytestream+= CABAC_BITS/8; | |||||
| } | |||||
| static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ | |||||
| int s = *state; | |||||
| int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; | |||||
| int bit, lps_mask; | |||||
| c->range -= RangeLPS; | |||||
| lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; | |||||
| c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; | |||||
| c->range += (RangeLPS - c->range) & lps_mask; | |||||
| s^=lps_mask; | |||||
| *state= (ff_h264_mlps_state+128)[s]; | |||||
| bit= s&1; | |||||
| lps_mask= ff_h264_norm_shift[c->range]; | |||||
| c->range<<= lps_mask; | |||||
| c->low <<= lps_mask; | |||||
| if(!(c->low & CABAC_MASK)) | |||||
| refill2(c); | |||||
| return bit; | |||||
| } | |||||
| #endif | |||||
| static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){ | |||||
| return get_cabac_inline(c,state); | |||||
| } | |||||
| static int av_unused get_cabac(CABACContext *c, uint8_t * const state){ | |||||
| return get_cabac_inline(c,state); | |||||
| } | |||||
| static int av_unused get_cabac_bypass(CABACContext *c){ | |||||
| int range; | |||||
| c->low += c->low; | |||||
| if(!(c->low & CABAC_MASK)) | |||||
| refill(c); | |||||
| range= c->range<<(CABAC_BITS+1); | |||||
| if(c->low < range){ | |||||
| return 0; | |||||
| }else{ | |||||
| c->low -= range; | |||||
| return 1; | |||||
| } | |||||
| } | |||||
| #ifndef get_cabac_bypass_sign | |||||
| static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ | |||||
| int range, mask; | |||||
| c->low += c->low; | |||||
| if(!(c->low & CABAC_MASK)) | |||||
| refill(c); | |||||
| range= c->range<<(CABAC_BITS+1); | |||||
| c->low -= range; | |||||
| mask= c->low >> 31; | |||||
| range &= mask; | |||||
| c->low += range; | |||||
| return (val^mask)-mask; | |||||
| } | |||||
| #endif | |||||
| /** | |||||
| * | |||||
| * @return the number of bytes read or 0 if no end | |||||
| */ | |||||
| static int av_unused get_cabac_terminate(CABACContext *c){ | |||||
| c->range -= 2; | |||||
| if(c->low < c->range<<(CABAC_BITS+1)){ | |||||
| renorm_cabac_decoder_once(c); | |||||
| return 0; | |||||
| }else{ | |||||
| return c->bytestream - c->bytestream_start; | |||||
| } | |||||
| } | |||||
| #endif /* AVCODEC_CABAC_FUNCTIONS_H */ | |||||
| @@ -30,6 +30,8 @@ | |||||
| #include "libavutil/imgutils.h" | #include "libavutil/imgutils.h" | ||||
| #include "libavutil/opt.h" | #include "libavutil/opt.h" | ||||
| #include "internal.h" | #include "internal.h" | ||||
| #include "cabac.h" | |||||
| #include "cabac_functions.h" | |||||
| #include "dsputil.h" | #include "dsputil.h" | ||||
| #include "avcodec.h" | #include "avcodec.h" | ||||
| #include "mpegvideo.h" | #include "mpegvideo.h" | ||||
| @@ -43,8 +45,6 @@ | |||||
| #include "vdpau_internal.h" | #include "vdpau_internal.h" | ||||
| #include "libavutil/avassert.h" | #include "libavutil/avassert.h" | ||||
| #include "cabac.h" | |||||
| //#undef NDEBUG | //#undef NDEBUG | ||||
| #include <assert.h> | #include <assert.h> | ||||
| @@ -28,6 +28,9 @@ | |||||
| #define CABAC 1 | #define CABAC 1 | ||||
| #define UNCHECKED_BITSTREAM_READER 1 | #define UNCHECKED_BITSTREAM_READER 1 | ||||
| #include "config.h" | |||||
| #include "cabac.h" | |||||
| #include "cabac_functions.h" | |||||
| #include "internal.h" | #include "internal.h" | ||||
| #include "dsputil.h" | #include "dsputil.h" | ||||
| #include "avcodec.h" | #include "avcodec.h" | ||||
| @@ -36,7 +39,6 @@ | |||||
| #include "h264_mvpred.h" | #include "h264_mvpred.h" | ||||
| #include "golomb.h" | #include "golomb.h" | ||||
| #include "cabac.h" | |||||
| #if ARCH_X86 | #if ARCH_X86 | ||||
| #include "x86/h264_i386.h" | #include "x86/h264_i386.h" | ||||
| #endif | #endif | ||||
| @@ -183,6 +183,25 @@ void rgb16tobgr32(const uint8_t *src, uint8_t *dst, int src_size) | |||||
| } | } | ||||
| } | } | ||||
| void rgb12to15(const uint8_t *src, uint8_t *dst, int src_size) | |||||
| { | |||||
| const uint16_t *end; | |||||
| uint16_t *d = (uint16_t *)dst; | |||||
| const uint16_t *s = (const uint16_t *)src; | |||||
| uint16_t rgb, r, g, b; | |||||
| end = s + src_size / 2; | |||||
| while (s < end) { | |||||
| rgb = *s++; | |||||
| r = rgb & 0xF00; | |||||
| g = rgb & 0x0F0; | |||||
| b = rgb & 0x00F; | |||||
| r = (r << 3) | ((r & 0x800) >> 1); | |||||
| g = (g << 2) | ((g & 0x080) >> 2); | |||||
| b = (b << 1) | ( b >> 3); | |||||
| *d++ = r | g | b; | |||||
| } | |||||
| } | |||||
| void rgb16to24(const uint8_t *src, uint8_t *dst, int src_size) | void rgb16to24(const uint8_t *src, uint8_t *dst, int src_size) | ||||
| { | { | ||||
| const uint16_t *end; | const uint16_t *end; | ||||
| @@ -63,6 +63,7 @@ void rgb15to24(const uint8_t *src, uint8_t *dst, int src_size); | |||||
| void rgb15tobgr16(const uint8_t *src, uint8_t *dst, int src_size); | void rgb15tobgr16(const uint8_t *src, uint8_t *dst, int src_size); | ||||
| void rgb15tobgr15(const uint8_t *src, uint8_t *dst, int src_size); | void rgb15tobgr15(const uint8_t *src, uint8_t *dst, int src_size); | ||||
| void rgb12tobgr12(const uint8_t *src, uint8_t *dst, int src_size); | void rgb12tobgr12(const uint8_t *src, uint8_t *dst, int src_size); | ||||
| void rgb12to15(const uint8_t *src, uint8_t *dst, int src_size); | |||||
| void shuffle_bytes_0321(const uint8_t *src, uint8_t *dst, int src_size); | void shuffle_bytes_0321(const uint8_t *src, uint8_t *dst, int src_size); | ||||
| void shuffle_bytes_1230(const uint8_t *src, uint8_t *dst, int src_size); | void shuffle_bytes_1230(const uint8_t *src, uint8_t *dst, int src_size); | ||||
| @@ -340,8 +340,8 @@ int main(int argc, char **argv) | |||||
| enum PixelFormat srcFormat = PIX_FMT_NONE; | enum PixelFormat srcFormat = PIX_FMT_NONE; | ||||
| enum PixelFormat dstFormat = PIX_FMT_NONE; | enum PixelFormat dstFormat = PIX_FMT_NONE; | ||||
| uint8_t *rgb_data = av_malloc(W * H * 4); | uint8_t *rgb_data = av_malloc(W * H * 4); | ||||
| uint8_t *rgb_src[3] = { rgb_data, NULL, NULL }; | |||||
| int rgb_stride[3] = { 4 * W, 0, 0 }; | |||||
| uint8_t *rgb_src[4] = { rgb_data, NULL, NULL, NULL }; | |||||
| int rgb_stride[4] = { 4 * W, 0, 0, 0 }; | |||||
| uint8_t *data = av_malloc(4 * W * H); | uint8_t *data = av_malloc(4 * W * H); | ||||
| uint8_t *src[4] = { data, data + W * H, data + W * H * 2, data + W * H * 3 }; | uint8_t *src[4] = { data, data + W * H, data + W * H * 2, data + W * H * 3 }; | ||||
| int stride[4] = { W, W, W, W }; | int stride[4] = { W, W, W, W }; | ||||
| @@ -396,17 +396,22 @@ static int planarRgbToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStr | |||||
| ) | ) | ||||
| /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */ | /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */ | ||||
| static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], | |||||
| int srcSliceY, int srcSliceH, uint8_t *dst[], | |||||
| int dstStride[]) | |||||
| typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int); | |||||
| static rgbConvFn findRgbConvFn(SwsContext *c) | |||||
| { | { | ||||
| const enum PixelFormat srcFormat = c->srcFormat; | const enum PixelFormat srcFormat = c->srcFormat; | ||||
| const enum PixelFormat dstFormat = c->dstFormat; | const enum PixelFormat dstFormat = c->dstFormat; | ||||
| const int srcBpp = (c->srcFormatBpp + 7) >> 3; | |||||
| const int dstBpp = (c->dstFormatBpp + 7) >> 3; | |||||
| const int srcId = c->srcFormatBpp; | const int srcId = c->srcFormatBpp; | ||||
| const int dstId = c->dstFormatBpp; | const int dstId = c->dstFormatBpp; | ||||
| void (*conv)(const uint8_t *src, uint8_t *dst, int src_size) = NULL; | |||||
| rgbConvFn conv = NULL; | |||||
| #define IS_NOT_NE(bpp, fmt) \ | |||||
| (((bpp + 7) >> 3) == 2 && \ | |||||
| (!(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_BE) != !HAVE_BIGENDIAN)) | |||||
| /* if this is non-native rgb444/555/565, don't handle it here. */ | |||||
| if (IS_NOT_NE(srcId, srcFormat) || IS_NOT_NE(dstId, dstFormat)) | |||||
| return NULL; | |||||
| #define CONV_IS(src, dst) (srcFormat == PIX_FMT_##src && dstFormat == PIX_FMT_##dst) | #define CONV_IS(src, dst) (srcFormat == PIX_FMT_##src && dstFormat == PIX_FMT_##dst) | ||||
| @@ -428,6 +433,7 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], | |||||
| if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) || | if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) || | ||||
| (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) { | (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) { | ||||
| switch (srcId | (dstId << 16)) { | switch (srcId | (dstId << 16)) { | ||||
| case 0x000F000C: conv = rgb12to15; break; | |||||
| case 0x000F0010: conv = rgb16to15; break; | case 0x000F0010: conv = rgb16to15; break; | ||||
| case 0x000F0018: conv = rgb24to15; break; | case 0x000F0018: conv = rgb24to15; break; | ||||
| case 0x000F0020: conv = rgb32to15; break; | case 0x000F0020: conv = rgb32to15; break; | ||||
| @@ -463,6 +469,21 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], | |||||
| } | } | ||||
| } | } | ||||
| return conv; | |||||
| } | |||||
| /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */ | |||||
| static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], | |||||
| int srcSliceY, int srcSliceH, uint8_t *dst[], | |||||
| int dstStride[]) | |||||
| { | |||||
| const enum PixelFormat srcFormat = c->srcFormat; | |||||
| const enum PixelFormat dstFormat = c->dstFormat; | |||||
| const int srcBpp = (c->srcFormatBpp + 7) >> 3; | |||||
| const int dstBpp = (c->dstFormatBpp + 7) >> 3; | |||||
| rgbConvFn conv = findRgbConvFn(c); | |||||
| if (!conv) { | if (!conv) { | ||||
| av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n", | av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n", | ||||
| av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat)); | av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat)); | ||||
| @@ -694,6 +715,8 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t *src[], | |||||
| } else { | } else { | ||||
| if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) | if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) | ||||
| length *= 2; | length *= 2; | ||||
| else if (!av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1) | |||||
| length >>= 3; // monowhite/black | |||||
| for (i = 0; i < height; i++) { | for (i = 0; i < height; i++) { | ||||
| memcpy(dstPtr, srcPtr, length); | memcpy(dstPtr, srcPtr, length); | ||||
| srcPtr += srcStride[plane]; | srcPtr += srcStride[plane]; | ||||
| @@ -748,24 +771,8 @@ void ff_get_unscaled_swscale(SwsContext *c) | |||||
| c->swScale = bgr24ToYv12Wrapper; | c->swScale = bgr24ToYv12Wrapper; | ||||
| /* RGB/BGR -> RGB/BGR (no dither needed forms) */ | /* RGB/BGR -> RGB/BGR (no dither needed forms) */ | ||||
| if ( isAnyRGB(srcFormat) | |||||
| && isAnyRGB(dstFormat) | |||||
| && srcFormat != PIX_FMT_BGR8 && dstFormat != PIX_FMT_BGR8 | |||||
| && srcFormat != PIX_FMT_RGB8 && dstFormat != PIX_FMT_RGB8 | |||||
| && srcFormat != PIX_FMT_BGR4 && dstFormat != PIX_FMT_BGR4 | |||||
| && srcFormat != PIX_FMT_RGB4 && dstFormat != PIX_FMT_RGB4 | |||||
| && srcFormat != PIX_FMT_BGR4_BYTE && dstFormat != PIX_FMT_BGR4_BYTE | |||||
| && srcFormat != PIX_FMT_RGB4_BYTE && dstFormat != PIX_FMT_RGB4_BYTE | |||||
| && srcFormat != PIX_FMT_MONOBLACK && dstFormat != PIX_FMT_MONOBLACK | |||||
| && srcFormat != PIX_FMT_MONOWHITE && dstFormat != PIX_FMT_MONOWHITE | |||||
| && srcFormat != PIX_FMT_RGB48LE && dstFormat != PIX_FMT_RGB48LE | |||||
| && srcFormat != PIX_FMT_RGB48BE && dstFormat != PIX_FMT_RGB48BE | |||||
| && srcFormat != PIX_FMT_BGR48LE && dstFormat != PIX_FMT_BGR48LE | |||||
| && srcFormat != PIX_FMT_BGR48BE && dstFormat != PIX_FMT_BGR48BE | |||||
| && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))) | |||||
| && (!(av_pix_fmt_descriptors[srcFormat].flags & PIX_FMT_BE) == !HAVE_BIGENDIAN || (c->srcFormatBpp+7)/8!=2) | |||||
| && (!(av_pix_fmt_descriptors[dstFormat].flags & PIX_FMT_BE) == !HAVE_BIGENDIAN || (c->dstFormatBpp+7)/8!=2) | |||||
| ) | |||||
| if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c) | |||||
| && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)))) | |||||
| c->swScale= rgbToRgbWrapper; | c->swScale= rgbToRgbWrapper; | ||||
| #define isByteRGB(f) (\ | #define isByteRGB(f) (\ | ||||
| @@ -30,6 +30,33 @@ fate-sunraster-24bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-raw. | |||||
| FATE_IMAGE += fate-sunraster-24bit-rle | FATE_IMAGE += fate-sunraster-24bit-rle | ||||
| fate-sunraster-24bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-rle.sun | fate-sunraster-24bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-rle.sun | ||||
| FATE_TESTS += $(FATE_IMAGE) | FATE_TESTS += $(FATE_IMAGE) | ||||
| fate-image: $(FATE_IMAGE) | fate-image: $(FATE_IMAGE) | ||||
| FATE_TARGA = CBW8 \ | |||||
| CTC16 \ | |||||
| CTC24 \ | |||||
| CTC32 \ | |||||
| UBW8 \ | |||||
| UTC16 \ | |||||
| UTC24 \ | |||||
| UTC32 | |||||
| FATE_TARGA := $(FATE_TARGA:%=fate-targa-conformance-%) \ | |||||
| fate-targa-top-to-bottom | |||||
| FATE_TESTS += $(FATE_TARGA) | |||||
| fate-targa: $(FATE_TARGA) | |||||
| fate-targa-conformance-CBW8: CMD = framecrc -i $(SAMPLES)/targa-conformance/CBW8.TGA | |||||
| # fate-targa-conformance-CCM8: CMD = framecrc -i $(SAMPLES)/targa-conformance/CCM8.TGA | |||||
| fate-targa-conformance-CTC16: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC16.TGA | |||||
| fate-targa-conformance-CTC24: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC24.TGA | |||||
| fate-targa-conformance-CTC32: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC32.TGA | |||||
| fate-targa-conformance-UBW8: CMD = framecrc -i $(SAMPLES)/targa-conformance/UBW8.TGA | |||||
| # fate-targa-conformance-UCM8: CMD = framecrc -i $(SAMPLES)/targa-conformance/UCM8.TGA | |||||
| fate-targa-conformance-UTC16: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC16.TGA | |||||
| fate-targa-conformance-UTC24: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC24.TGA | |||||
| fate-targa-conformance-UTC32: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC32.TGA | |||||
| fate-targa-top-to-bottom: CMD = framecrc -i $(SAMPLES)/targa/lena-top-to-bottom.tga | |||||
| @@ -0,0 +1 @@ | |||||
| 0, 0, 16384, 0x267e21ef | |||||
| @@ -0,0 +1 @@ | |||||
| 0, 0, 32768, 0xa6b3d20d | |||||
| @@ -0,0 +1 @@ | |||||
| 0, 0, 49152, 0xaca4bc29 | |||||
| @@ -0,0 +1 @@ | |||||
| 0, 0, 65536, 0xcf98bc29 | |||||
| @@ -0,0 +1 @@ | |||||
| 0, 0, 16384, 0x267e21ef | |||||
| @@ -0,0 +1 @@ | |||||
| 0, 0, 32768, 0xa6b3d20d | |||||
| @@ -0,0 +1 @@ | |||||
| 0, 0, 49152, 0xaca4bc29 | |||||
| @@ -0,0 +1 @@ | |||||
| 0, 0, 65536, 0xcf98bc29 | |||||
| @@ -0,0 +1 @@ | |||||
| 0, 0, 196608, 0xb29ec51a | |||||