* 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
Unified · Split
| @@ -68,6 +68,7 @@ ELF .size \name, . - \name · 67 unmodified lines | ||
| 68 | 68 | .purgem endfunc |
| 69 | 69 | .endm |
| 70 | 70 | .text |
| 71 | + .align 2 | |
| 71 | 72 | .if \export |
| 72 | 73 | .global EXTERN_ASM\name |
| 73 | 74 | EXTERN_ASM\name: |
| @@ -491,8 +491,8 @@ __end_bef_a_evaluation: · 490 unmodified lines | ||
| 491 | 491 | bal __end_a_evaluation |
| 492 | 492 | |
| 493 | 493 | |
| 494 | −__constant_ptr__: @@ see #defines at the beginning of the source code for values. | |
| 495 | 494 | .align |
| 495 | +__constant_ptr__: @@ see #defines at the beginning of the source code for values. | |
| 496 | 496 | .word W1 |
| 497 | 497 | .word W2 |
| 498 | 498 | .word W3 |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include "libavutil/common.h" |
| 30 | 30 | #include "get_bits.h" |
| 31 | 31 | #include "cabac.h" |
| 32 | +#include "cabac_functions.h" | |
| 32 | 33 | |
| 33 | 34 | static const uint8_t lps_range[64][4]= { |
| 34 | 35 | {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]= { · 16 unmodified lines | ||
| 51 | 52 | |
| 52 | 53 | uint8_t ff_h264_mlps_state[4*64]; |
| 53 | 54 | uint8_t ff_h264_lps_range[4*2*64]; |
| 54 | −uint8_t ff_h264_lps_state[2*64]; | |
| 55 | −uint8_t ff_h264_mps_state[2*64]; | |
| 55 | +static uint8_t h264_mps_state[2 * 64]; | |
| 56 | 56 | |
| 57 | 57 | static const uint8_t mps_state[64]= { |
| 58 | 58 | 1, 2, 3, 4, 5, 6, 7, 8, |
| @@ -141,9 +141,9 @@ void ff_init_cabac_states(CABACContext *c){ · 82 unmodified lines | ||
| 141 | 141 | } |
| 142 | 142 | |
| 143 | 143 | ff_h264_mlps_state[128+2*i+0]= |
| 144 | − ff_h264_mps_state[2*i+0]= 2*mps_state[i]+0; | |
| 144 | + h264_mps_state[2 * i + 0] = 2 * mps_state[i] + 0; | |
| 145 | 145 | ff_h264_mlps_state[128+2*i+1]= |
| 146 | − ff_h264_mps_state[2*i+1]= 2*mps_state[i]+1; | |
| 146 | + h264_mps_state[2 * i + 1] = 2 * mps_state[i] + 1; | |
| 147 | 147 | |
| 148 | 148 | if( i ){ |
| 149 | 149 | ff_h264_lps_state[2*i+0]= |
| @@ -196,11 +196,10 @@ static void put_cabac(CABACContext *c, uint8_t * const state, int bit){ · 46 unmodified lines | ||
| 196 | 196 | |
| 197 | 197 | if(bit == ((*state)&1)){ |
| 198 | 198 | c->range -= RangeLPS; |
| 199 | − *state= ff_h264_mps_state[*state]; | |
| 199 | + *state = h264_mps_state[*state]; | |
| 200 | 200 | }else{ |
| 201 | 201 | c->low += c->range - RangeLPS; |
| 202 | 202 | c->range = RangeLPS; |
| 203 | − *state= ff_h264_lps_state[*state]; | |
| 204 | 203 | } |
| 205 | 204 | |
| 206 | 205 | renorm_cabac_encoder(c); |
| @@ -27,13 +27,10 @@ · 26 unmodified lines | ||
| 27 | 27 | #ifndef AVCODEC_CABAC_H |
| 28 | 28 | #define AVCODEC_CABAC_H |
| 29 | 29 | |
| 30 | −#include <stddef.h> | |
| 30 | +#include <stdint.h> | |
| 31 | 31 | |
| 32 | 32 | #include "put_bits.h" |
| 33 | 33 | |
| 34 | −//#undef NDEBUG | |
| 35 | −#include <assert.h> | |
| 36 | − | |
| 37 | 34 | #define CABAC_BITS 16 |
| 38 | 35 | #define CABAC_MASK ((1<<CABAC_BITS)-1) |
| 39 | 36 | |
| @@ -47,136 +44,8 @@ typedef struct CABACContext{ · 7 unmodified lines | ||
| 47 | 44 | PutBitContext pb; |
| 48 | 45 | }CABACContext; |
| 49 | 46 | |
| 50 | −extern uint8_t ff_h264_mlps_state[4*64]; | |
| 51 | −extern uint8_t ff_h264_lps_range[4*2*64]; ///< rangeTabLPS | |
| 52 | −extern uint8_t ff_h264_mps_state[2*64]; ///< transIdxMPS | |
| 53 | −extern uint8_t ff_h264_lps_state[2*64]; ///< transIdxLPS | |
| 54 | −extern const uint8_t ff_h264_norm_shift[512]; | |
| 55 | − | |
| 56 | −#if ARCH_X86 | |
| 57 | −# include "x86/cabac.h" | |
| 58 | −#endif | |
| 59 | − | |
| 60 | 47 | void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size); |
| 61 | 48 | void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size); |
| 62 | 49 | void ff_init_cabac_states(CABACContext *c); |
| 63 | 50 | |
| 64 | − | |
| 65 | −static void refill(CABACContext *c){ | |
| 66 | −#if CABAC_BITS == 16 | |
| 67 | − c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); | |
| 68 | −#else | |
| 69 | − c->low+= c->bytestream[0]<<1; | |
| 70 | −#endif | |
| 71 | − c->low -= CABAC_MASK; | |
| 72 | − c->bytestream+= CABAC_BITS/8; | |
| 73 | −} | |
| 74 | − | |
| 75 | −static inline void renorm_cabac_decoder_once(CABACContext *c){ | |
| 76 | − int shift= (uint32_t)(c->range - 0x100)>>31; | |
| 77 | − c->range<<= shift; | |
| 78 | − c->low <<= shift; | |
| 79 | − if(!(c->low & CABAC_MASK)) | |
| 80 | − refill(c); | |
| 81 | −} | |
| 82 | − | |
| 83 | −#ifndef get_cabac_inline | |
| 84 | −static void refill2(CABACContext *c){ | |
| 85 | − int i, x; | |
| 86 | − | |
| 87 | − x= c->low ^ (c->low-1); | |
| 88 | − i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; | |
| 89 | − | |
| 90 | − x= -CABAC_MASK; | |
| 91 | − | |
| 92 | −#if CABAC_BITS == 16 | |
| 93 | − x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); | |
| 94 | −#else | |
| 95 | − x+= c->bytestream[0]<<1; | |
| 96 | −#endif | |
| 97 | − | |
| 98 | − c->low += x<<i; | |
| 99 | − c->bytestream+= CABAC_BITS/8; | |
| 100 | −} | |
| 101 | − | |
| 102 | −static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ | |
| 103 | − int s = *state; | |
| 104 | − int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; | |
| 105 | − int bit, lps_mask; | |
| 106 | − | |
| 107 | − c->range -= RangeLPS; | |
| 108 | − lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; | |
| 109 | − | |
| 110 | − c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; | |
| 111 | − c->range += (RangeLPS - c->range) & lps_mask; | |
| 112 | − | |
| 113 | − s^=lps_mask; | |
| 114 | − *state= (ff_h264_mlps_state+128)[s]; | |
| 115 | − bit= s&1; | |
| 116 | − | |
| 117 | − lps_mask= ff_h264_norm_shift[c->range]; | |
| 118 | − c->range<<= lps_mask; | |
| 119 | − c->low <<= lps_mask; | |
| 120 | − if(!(c->low & CABAC_MASK)) | |
| 121 | − refill2(c); | |
| 122 | − return bit; | |
| 123 | −} | |
| 124 | −#endif | |
| 125 | − | |
| 126 | −static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){ | |
| 127 | − return get_cabac_inline(c,state); | |
| 128 | −} | |
| 129 | − | |
| 130 | −static int av_unused get_cabac(CABACContext *c, uint8_t * const state){ | |
| 131 | − return get_cabac_inline(c,state); | |
| 132 | −} | |
| 133 | − | |
| 134 | −static int av_unused get_cabac_bypass(CABACContext *c){ | |
| 135 | − int range; | |
| 136 | − c->low += c->low; | |
| 137 | − | |
| 138 | − if(!(c->low & CABAC_MASK)) | |
| 139 | − refill(c); | |
| 140 | − | |
| 141 | − range= c->range<<(CABAC_BITS+1); | |
| 142 | − if(c->low < range){ | |
| 143 | − return 0; | |
| 144 | − }else{ | |
| 145 | − c->low -= range; | |
| 146 | − return 1; | |
| 147 | − } | |
| 148 | −} | |
| 149 | − | |
| 150 | − | |
| 151 | −#ifndef get_cabac_bypass_sign | |
| 152 | −static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ | |
| 153 | − int range, mask; | |
| 154 | − c->low += c->low; | |
| 155 | − | |
| 156 | − if(!(c->low & CABAC_MASK)) | |
| 157 | − refill(c); | |
| 158 | − | |
| 159 | − range= c->range<<(CABAC_BITS+1); | |
| 160 | − c->low -= range; | |
| 161 | − mask= c->low >> 31; | |
| 162 | − range &= mask; | |
| 163 | − c->low += range; | |
| 164 | − return (val^mask)-mask; | |
| 165 | −} | |
| 166 | −#endif | |
| 167 | − | |
| 168 | −/** | |
| 169 | − * | |
| 170 | − * @return the number of bytes read or 0 if no end | |
| 171 | − */ | |
| 172 | −static int av_unused get_cabac_terminate(CABACContext *c){ | |
| 173 | − c->range -= 2; | |
| 174 | − if(c->low < c->range<<(CABAC_BITS+1)){ | |
| 175 | − renorm_cabac_decoder_once(c); | |
| 176 | − return 0; | |
| 177 | − }else{ | |
| 178 | − return c->bytestream - c->bytestream_start; | |
| 179 | − } | |
| 180 | −} | |
| 181 | − | |
| 182 | 51 | #endif /* AVCODEC_CABAC_H */ |
| @@ -0,0 +1,160 @@ | ||
| 1 | +/* | |
| 2 | + * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder | |
| 3 | + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> | |
| 4 | + * | |
| 5 | + * This file is part of Libav. | |
| 6 | + * | |
| 7 | + * Libav is free software; you can redistribute it and/or | |
| 8 | + * modify it under the terms of the GNU Lesser General Public | |
| 9 | + * License as published by the Free Software Foundation; either | |
| 10 | + * version 2.1 of the License, or (at your option) any later version. | |
| 11 | + * | |
| 12 | + * Libav is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 | + * Lesser General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU Lesser General Public | |
| 18 | + * License along with Libav; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 20 | + */ | |
| 21 | + | |
| 22 | +/** | |
| 23 | + * @file | |
| 24 | + * Context Adaptive Binary Arithmetic Coder inline functions | |
| 25 | + */ | |
| 26 | + | |
| 27 | +#ifndef AVCODEC_CABAC_FUNCTIONS_H | |
| 28 | +#define AVCODEC_CABAC_FUNCTIONS_H | |
| 29 | + | |
| 30 | +#include <stdint.h> | |
| 31 | + | |
| 32 | +#include "cabac.h" | |
| 33 | +#include "config.h" | |
| 34 | + | |
| 35 | +#if ARCH_X86 | |
| 36 | +# include "x86/cabac.h" | |
| 37 | +#endif | |
| 38 | + | |
| 39 | +extern const uint8_t ff_h264_norm_shift[512]; | |
| 40 | +extern uint8_t ff_h264_mlps_state[4*64]; | |
| 41 | +extern uint8_t ff_h264_lps_range[4*2*64]; ///< rangeTabLPS | |
| 42 | + | |
| 43 | +static void refill(CABACContext *c){ | |
| 44 | +#if CABAC_BITS == 16 | |
| 45 | + c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); | |
| 46 | +#else | |
| 47 | + c->low+= c->bytestream[0]<<1; | |
| 48 | +#endif | |
| 49 | + c->low -= CABAC_MASK; | |
| 50 | + c->bytestream+= CABAC_BITS/8; | |
| 51 | +} | |
| 52 | + | |
| 53 | +static inline void renorm_cabac_decoder_once(CABACContext *c){ | |
| 54 | + int shift= (uint32_t)(c->range - 0x100)>>31; | |
| 55 | + c->range<<= shift; | |
| 56 | + c->low <<= shift; | |
| 57 | + if(!(c->low & CABAC_MASK)) | |
| 58 | + refill(c); | |
| 59 | +} | |
| 60 | + | |
| 61 | +#ifndef get_cabac_inline | |
| 62 | +static void refill2(CABACContext *c){ | |
| 63 | + int i, x; | |
| 64 | + | |
| 65 | + x= c->low ^ (c->low-1); | |
| 66 | + i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; | |
| 67 | + | |
| 68 | + x= -CABAC_MASK; | |
| 69 | + | |
| 70 | +#if CABAC_BITS == 16 | |
| 71 | + x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); | |
| 72 | +#else | |
| 73 | + x+= c->bytestream[0]<<1; | |
| 74 | +#endif | |
| 75 | + | |
| 76 | + c->low += x<<i; | |
| 77 | + c->bytestream+= CABAC_BITS/8; | |
| 78 | +} | |
| 79 | + | |
| 80 | +static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ | |
| 81 | + int s = *state; | |
| 82 | + int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; | |
| 83 | + int bit, lps_mask; | |
| 84 | + | |
| 85 | + c->range -= RangeLPS; | |
| 86 | + lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; | |
| 87 | + | |
| 88 | + c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; | |
| 89 | + c->range += (RangeLPS - c->range) & lps_mask; | |
| 90 | + | |
| 91 | + s^=lps_mask; | |
| 92 | + *state= (ff_h264_mlps_state+128)[s]; | |
| 93 | + bit= s&1; | |
| 94 | + | |
| 95 | + lps_mask= ff_h264_norm_shift[c->range]; | |
| 96 | + c->range<<= lps_mask; | |
| 97 | + c->low <<= lps_mask; | |
| 98 | + if(!(c->low & CABAC_MASK)) | |
| 99 | + refill2(c); | |
| 100 | + return bit; | |
| 101 | +} | |
| 102 | +#endif | |
| 103 | + | |
| 104 | +static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){ | |
| 105 | + return get_cabac_inline(c,state); | |
| 106 | +} | |
| 107 | + | |
| 108 | +static int av_unused get_cabac(CABACContext *c, uint8_t * const state){ | |
| 109 | + return get_cabac_inline(c,state); | |
| 110 | +} | |
| 111 | + | |
| 112 | +static int av_unused get_cabac_bypass(CABACContext *c){ | |
| 113 | + int range; | |
| 114 | + c->low += c->low; | |
| 115 | + | |
| 116 | + if(!(c->low & CABAC_MASK)) | |
| 117 | + refill(c); | |
| 118 | + | |
| 119 | + range= c->range<<(CABAC_BITS+1); | |
| 120 | + if(c->low < range){ | |
| 121 | + return 0; | |
| 122 | + }else{ | |
| 123 | + c->low -= range; | |
| 124 | + return 1; | |
| 125 | + } | |
| 126 | +} | |
| 127 | + | |
| 128 | + | |
| 129 | +#ifndef get_cabac_bypass_sign | |
| 130 | +static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ | |
| 131 | + int range, mask; | |
| 132 | + c->low += c->low; | |
| 133 | + | |
| 134 | + if(!(c->low & CABAC_MASK)) | |
| 135 | + refill(c); | |
| 136 | + | |
| 137 | + range= c->range<<(CABAC_BITS+1); | |
| 138 | + c->low -= range; | |
| 139 | + mask= c->low >> 31; | |
| 140 | + range &= mask; | |
| 141 | + c->low += range; | |
| 142 | + return (val^mask)-mask; | |
| 143 | +} | |
| 144 | +#endif | |
| 145 | + | |
| 146 | +/** | |
| 147 | + * | |
| 148 | + * @return the number of bytes read or 0 if no end | |
| 149 | + */ | |
| 150 | +static int av_unused get_cabac_terminate(CABACContext *c){ | |
| 151 | + c->range -= 2; | |
| 152 | + if(c->low < c->range<<(CABAC_BITS+1)){ | |
| 153 | + renorm_cabac_decoder_once(c); | |
| 154 | + return 0; | |
| 155 | + }else{ | |
| 156 | + return c->bytestream - c->bytestream_start; | |
| 157 | + } | |
| 158 | +} | |
| 159 | + | |
| 160 | +#endif /* AVCODEC_CABAC_FUNCTIONS_H */ | |
| @@ -30,6 +30,8 @@ · 29 unmodified lines | ||
| 30 | 30 | #include "libavutil/imgutils.h" |
| 31 | 31 | #include "libavutil/opt.h" |
| 32 | 32 | #include "internal.h" |
| 33 | +#include "cabac.h" | |
| 34 | +#include "cabac_functions.h" | |
| 33 | 35 | #include "dsputil.h" |
| 34 | 36 | #include "avcodec.h" |
| 35 | 37 | #include "mpegvideo.h" |
| @@ -43,8 +45,6 @@ · 7 unmodified lines | ||
| 43 | 45 | #include "vdpau_internal.h" |
| 44 | 46 | #include "libavutil/avassert.h" |
| 45 | 47 | |
| 46 | −#include "cabac.h" | |
| 47 | − | |
| 48 | 48 | //#undef NDEBUG |
| 49 | 49 | #include <assert.h> |
| 50 | 50 | |
| @@ -28,6 +28,9 @@ · 27 unmodified lines | ||
| 28 | 28 | #define CABAC 1 |
| 29 | 29 | #define UNCHECKED_BITSTREAM_READER 1 |
| 30 | 30 | |
| 31 | +#include "config.h" | |
| 32 | +#include "cabac.h" | |
| 33 | +#include "cabac_functions.h" | |
| 31 | 34 | #include "internal.h" |
| 32 | 35 | #include "dsputil.h" |
| 33 | 36 | #include "avcodec.h" |
| @@ -36,7 +39,6 @@ · 2 unmodified lines | ||
| 36 | 39 | #include "h264_mvpred.h" |
| 37 | 40 | #include "golomb.h" |
| 38 | 41 | |
| 39 | −#include "cabac.h" | |
| 40 | 42 | #if ARCH_X86 |
| 41 | 43 | #include "x86/h264_i386.h" |
| 42 | 44 | #endif |
| @@ -183,6 +183,25 @@ void rgb16tobgr32(const uint8_t *src, uint8_t *dst, int src_size) · 182 unmodified lines | ||
| 183 | 183 | } |
| 184 | 184 | } |
| 185 | 185 | |
| 186 | +void rgb12to15(const uint8_t *src, uint8_t *dst, int src_size) | |
| 187 | +{ | |
| 188 | + const uint16_t *end; | |
| 189 | + uint16_t *d = (uint16_t *)dst; | |
| 190 | + const uint16_t *s = (const uint16_t *)src; | |
| 191 | + uint16_t rgb, r, g, b; | |
| 192 | + end = s + src_size / 2; | |
| 193 | + while (s < end) { | |
| 194 | + rgb = *s++; | |
| 195 | + r = rgb & 0xF00; | |
| 196 | + g = rgb & 0x0F0; | |
| 197 | + b = rgb & 0x00F; | |
| 198 | + r = (r << 3) | ((r & 0x800) >> 1); | |
| 199 | + g = (g << 2) | ((g & 0x080) >> 2); | |
| 200 | + b = (b << 1) | ( b >> 3); | |
| 201 | + *d++ = r | g | b; | |
| 202 | + } | |
| 203 | +} | |
| 204 | + | |
| 186 | 205 | void rgb16to24(const uint8_t *src, uint8_t *dst, int src_size) |
| 187 | 206 | { |
| 188 | 207 | const uint16_t *end; |
| @@ -63,6 +63,7 @@ void rgb15to24(const uint8_t *src, uint8_t *dst, int src_size); · 62 unmodified lines | ||
| 63 | 63 | void rgb15tobgr16(const uint8_t *src, uint8_t *dst, int src_size); |
| 64 | 64 | void rgb15tobgr15(const uint8_t *src, uint8_t *dst, int src_size); |
| 65 | 65 | void rgb12tobgr12(const uint8_t *src, uint8_t *dst, int src_size); |
| 66 | +void rgb12to15(const uint8_t *src, uint8_t *dst, int src_size); | |
| 66 | 67 | |
| 67 | 68 | void shuffle_bytes_0321(const uint8_t *src, uint8_t *dst, int src_size); |
| 68 | 69 | void shuffle_bytes_1230(const uint8_t *src, uint8_t *dst, int src_size); |
| @@ -340,8 +340,8 @@ int main(int argc, char **argv) · 339 unmodified lines | ||
| 340 | 340 | enum PixelFormat srcFormat = PIX_FMT_NONE; |
| 341 | 341 | enum PixelFormat dstFormat = PIX_FMT_NONE; |
| 342 | 342 | uint8_t *rgb_data = av_malloc(W * H * 4); |
| 343 | − uint8_t *rgb_src[3] = { rgb_data, NULL, NULL }; | |
| 344 | − int rgb_stride[3] = { 4 * W, 0, 0 }; | |
| 343 | + uint8_t *rgb_src[4] = { rgb_data, NULL, NULL, NULL }; | |
| 344 | + int rgb_stride[4] = { 4 * W, 0, 0, 0 }; | |
| 345 | 345 | uint8_t *data = av_malloc(4 * W * H); |
| 346 | 346 | uint8_t *src[4] = { data, data + W * H, data + W * H * 2, data + W * H * 3 }; |
| 347 | 347 | int stride[4] = { W, W, W, W }; |
| @@ -396,17 +396,22 @@ static int planarRgbToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStr · 395 unmodified lines | ||
| 396 | 396 | ) |
| 397 | 397 | |
| 398 | 398 | /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */ |
| 399 | −static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], | |
| 400 | − int srcSliceY, int srcSliceH, uint8_t *dst[], | |
| 401 | − int dstStride[]) | |
| 399 | +typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int); | |
| 400 | +static rgbConvFn findRgbConvFn(SwsContext *c) | |
| 402 | 401 | { |
| 403 | 402 | const enum PixelFormat srcFormat = c->srcFormat; |
| 404 | 403 | const enum PixelFormat dstFormat = c->dstFormat; |
| 405 | − const int srcBpp = (c->srcFormatBpp + 7) >> 3; | |
| 406 | − const int dstBpp = (c->dstFormatBpp + 7) >> 3; | |
| 407 | 404 | const int srcId = c->srcFormatBpp; |
| 408 | 405 | const int dstId = c->dstFormatBpp; |
| 409 | − void (*conv)(const uint8_t *src, uint8_t *dst, int src_size) = NULL; | |
| 406 | + rgbConvFn conv = NULL; | |
| 407 | + | |
| 408 | +#define IS_NOT_NE(bpp, fmt) \ | |
| 409 | + (((bpp + 7) >> 3) == 2 && \ | |
| 410 | + (!(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_BE) != !HAVE_BIGENDIAN)) | |
| 411 | + | |
| 412 | + /* if this is non-native rgb444/555/565, don't handle it here. */ | |
| 413 | + if (IS_NOT_NE(srcId, srcFormat) || IS_NOT_NE(dstId, dstFormat)) | |
| 414 | + return NULL; | |
| 410 | 415 | |
| 411 | 416 | #define CONV_IS(src, dst) (srcFormat == PIX_FMT_##src && dstFormat == PIX_FMT_##dst) |
| 412 | 417 | |
| @@ -428,6 +433,7 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], · 15 unmodified lines | ||
| 428 | 433 | if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) || |
| 429 | 434 | (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) { |
| 430 | 435 | switch (srcId | (dstId << 16)) { |
| 436 | + case 0x000F000C: conv = rgb12to15; break; | |
| 431 | 437 | case 0x000F0010: conv = rgb16to15; break; |
| 432 | 438 | case 0x000F0018: conv = rgb24to15; break; |
| 433 | 439 | case 0x000F0020: conv = rgb32to15; break; |
| @@ -463,6 +469,21 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], · 29 unmodified lines | ||
| 463 | 469 | } |
| 464 | 470 | } |
| 465 | 471 | |
| 472 | + return conv; | |
| 473 | +} | |
| 474 | + | |
| 475 | +/* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */ | |
| 476 | +static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], | |
| 477 | + int srcSliceY, int srcSliceH, uint8_t *dst[], | |
| 478 | + int dstStride[]) | |
| 479 | + | |
| 480 | +{ | |
| 481 | + const enum PixelFormat srcFormat = c->srcFormat; | |
| 482 | + const enum PixelFormat dstFormat = c->dstFormat; | |
| 483 | + const int srcBpp = (c->srcFormatBpp + 7) >> 3; | |
| 484 | + const int dstBpp = (c->dstFormatBpp + 7) >> 3; | |
| 485 | + rgbConvFn conv = findRgbConvFn(c); | |
| 486 | + | |
| 466 | 487 | if (!conv) { |
| 467 | 488 | av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n", |
| 468 | 489 | 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[], · 225 unmodified lines | ||
| 694 | 715 | } else { |
| 695 | 716 | if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) |
| 696 | 717 | length *= 2; |
| 718 | + else if (!av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1) | |
| 719 | + length >>= 3; // monowhite/black | |
| 697 | 720 | for (i = 0; i < height; i++) { |
| 698 | 721 | memcpy(dstPtr, srcPtr, length); |
| 699 | 722 | srcPtr += srcStride[plane]; |
| @@ -748,24 +771,8 @@ void ff_get_unscaled_swscale(SwsContext *c) · 48 unmodified lines | ||
| 748 | 771 | c->swScale = bgr24ToYv12Wrapper; |
| 749 | 772 | |
| 750 | 773 | /* RGB/BGR -> RGB/BGR (no dither needed forms) */ |
| 751 | − if ( isAnyRGB(srcFormat) | |
| 752 | − && isAnyRGB(dstFormat) | |
| 753 | − && srcFormat != PIX_FMT_BGR8 && dstFormat != PIX_FMT_BGR8 | |
| 754 | − && srcFormat != PIX_FMT_RGB8 && dstFormat != PIX_FMT_RGB8 | |
| 755 | − && srcFormat != PIX_FMT_BGR4 && dstFormat != PIX_FMT_BGR4 | |
| 756 | − && srcFormat != PIX_FMT_RGB4 && dstFormat != PIX_FMT_RGB4 | |
| 757 | − && srcFormat != PIX_FMT_BGR4_BYTE && dstFormat != PIX_FMT_BGR4_BYTE | |
| 758 | − && srcFormat != PIX_FMT_RGB4_BYTE && dstFormat != PIX_FMT_RGB4_BYTE | |
| 759 | − && srcFormat != PIX_FMT_MONOBLACK && dstFormat != PIX_FMT_MONOBLACK | |
| 760 | − && srcFormat != PIX_FMT_MONOWHITE && dstFormat != PIX_FMT_MONOWHITE | |
| 761 | − && srcFormat != PIX_FMT_RGB48LE && dstFormat != PIX_FMT_RGB48LE | |
| 762 | − && srcFormat != PIX_FMT_RGB48BE && dstFormat != PIX_FMT_RGB48BE | |
| 763 | − && srcFormat != PIX_FMT_BGR48LE && dstFormat != PIX_FMT_BGR48LE | |
| 764 | − && srcFormat != PIX_FMT_BGR48BE && dstFormat != PIX_FMT_BGR48BE | |
| 765 | − && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))) | |
| 766 | − && (!(av_pix_fmt_descriptors[srcFormat].flags & PIX_FMT_BE) == !HAVE_BIGENDIAN || (c->srcFormatBpp+7)/8!=2) | |
| 767 | − && (!(av_pix_fmt_descriptors[dstFormat].flags & PIX_FMT_BE) == !HAVE_BIGENDIAN || (c->dstFormatBpp+7)/8!=2) | |
| 768 | − ) | |
| 774 | + if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c) | |
| 775 | + && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)))) | |
| 769 | 776 | c->swScale= rgbToRgbWrapper; |
| 770 | 777 | |
| 771 | 778 | #define isByteRGB(f) (\ |
| @@ -30,6 +30,33 @@ fate-sunraster-24bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-raw. · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 31 | FATE_IMAGE += fate-sunraster-24bit-rle |
| 32 | 32 | fate-sunraster-24bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-rle.sun |
| 33 | − | |
| 34 | 33 | FATE_TESTS += $(FATE_IMAGE) |
| 35 | 34 | fate-image: $(FATE_IMAGE) |
| 35 | + | |
| 36 | +FATE_TARGA = CBW8 \ | |
| 37 | + CTC16 \ | |
| 38 | + CTC24 \ | |
| 39 | + CTC32 \ | |
| 40 | + UBW8 \ | |
| 41 | + UTC16 \ | |
| 42 | + UTC24 \ | |
| 43 | + UTC32 | |
| 44 | + | |
| 45 | +FATE_TARGA := $(FATE_TARGA:%=fate-targa-conformance-%) \ | |
| 46 | + fate-targa-top-to-bottom | |
| 47 | + | |
| 48 | +FATE_TESTS += $(FATE_TARGA) | |
| 49 | +fate-targa: $(FATE_TARGA) | |
| 50 | + | |
| 51 | +fate-targa-conformance-CBW8: CMD = framecrc -i $(SAMPLES)/targa-conformance/CBW8.TGA | |
| 52 | +# fate-targa-conformance-CCM8: CMD = framecrc -i $(SAMPLES)/targa-conformance/CCM8.TGA | |
| 53 | +fate-targa-conformance-CTC16: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC16.TGA | |
| 54 | +fate-targa-conformance-CTC24: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC24.TGA | |
| 55 | +fate-targa-conformance-CTC32: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC32.TGA | |
| 56 | +fate-targa-conformance-UBW8: CMD = framecrc -i $(SAMPLES)/targa-conformance/UBW8.TGA | |
| 57 | +# fate-targa-conformance-UCM8: CMD = framecrc -i $(SAMPLES)/targa-conformance/UCM8.TGA | |
| 58 | +fate-targa-conformance-UTC16: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC16.TGA | |
| 59 | +fate-targa-conformance-UTC24: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC24.TGA | |
| 60 | +fate-targa-conformance-UTC32: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC32.TGA | |
| 61 | + | |
| 62 | +fate-targa-top-to-bottom: CMD = framecrc -i $(SAMPLES)/targa/lena-top-to-bottom.tga | |
| @@ -0,0 +1 @@ | ||
| 1 | +0, 0, 16384, 0x267e21ef | |
| @@ -0,0 +1 @@ | ||
| 1 | +0, 0, 32768, 0xa6b3d20d | |
| @@ -0,0 +1 @@ | ||
| 1 | +0, 0, 49152, 0xaca4bc29 | |
| @@ -0,0 +1 @@ | ||
| 1 | +0, 0, 65536, 0xcf98bc29 | |
| @@ -0,0 +1 @@ | ||
| 1 | +0, 0, 16384, 0x267e21ef | |
| @@ -0,0 +1 @@ | ||
| 1 | +0, 0, 32768, 0xa6b3d20d | |
| @@ -0,0 +1 @@ | ||
| 1 | +0, 0, 49152, 0xaca4bc29 | |
| @@ -0,0 +1 @@ | ||
| 1 | +0, 0, 65536, 0xcf98bc29 | |
| @@ -0,0 +1 @@ | ||
| 1 | +0, 0, 196608, 0xb29ec51a | |