* 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>
| ... | ... |
@@ -491,8 +491,8 @@ __end_bef_a_evaluation: |
| 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 @@ |
| 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]= {
|
| 51 | 51 |
|
| 52 | 52 |
uint8_t ff_h264_mlps_state[4*64]; |
| 53 | 53 |
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]; |
|
| 54 |
+static uint8_t h264_mps_state[2 * 64]; |
|
| 56 | 55 |
|
| 57 | 56 |
static const uint8_t mps_state[64]= {
|
| 58 | 57 |
1, 2, 3, 4, 5, 6, 7, 8, |
| ... | ... |
@@ -141,9 +141,9 @@ void ff_init_cabac_states(CABACContext *c){
|
| 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){
|
| 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 @@ |
| 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{
|
| 47 | 47 |
PutBitContext pb; |
| 48 | 48 |
}CABACContext; |
| 49 | 49 |
|
| 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 | 50 |
void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size); |
| 61 | 51 |
void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size); |
| 62 | 52 |
void ff_init_cabac_states(CABACContext *c); |
| 63 | 53 |
|
| 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 | 54 |
#endif /* AVCODEC_CABAC_H */ |
| 183 | 55 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,160 @@ |
| 0 |
+/* |
|
| 1 |
+ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder |
|
| 2 |
+ * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> |
|
| 3 |
+ * |
|
| 4 |
+ * This file is part of Libav. |
|
| 5 |
+ * |
|
| 6 |
+ * Libav is free software; you can redistribute it and/or |
|
| 7 |
+ * modify it under the terms of the GNU Lesser General Public |
|
| 8 |
+ * License as published by the Free Software Foundation; either |
|
| 9 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
| 10 |
+ * |
|
| 11 |
+ * Libav is distributed in the hope that it will be useful, |
|
| 12 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 13 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
| 14 |
+ * Lesser General Public License for more details. |
|
| 15 |
+ * |
|
| 16 |
+ * You should have received a copy of the GNU Lesser General Public |
|
| 17 |
+ * License along with Libav; if not, write to the Free Software |
|
| 18 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
| 19 |
+ */ |
|
| 20 |
+ |
|
| 21 |
+/** |
|
| 22 |
+ * @file |
|
| 23 |
+ * Context Adaptive Binary Arithmetic Coder inline functions |
|
| 24 |
+ */ |
|
| 25 |
+ |
|
| 26 |
+#ifndef AVCODEC_CABAC_FUNCTIONS_H |
|
| 27 |
+#define AVCODEC_CABAC_FUNCTIONS_H |
|
| 28 |
+ |
|
| 29 |
+#include <stdint.h> |
|
| 30 |
+ |
|
| 31 |
+#include "cabac.h" |
|
| 32 |
+#include "config.h" |
|
| 33 |
+ |
|
| 34 |
+#if ARCH_X86 |
|
| 35 |
+# include "x86/cabac.h" |
|
| 36 |
+#endif |
|
| 37 |
+ |
|
| 38 |
+extern const uint8_t ff_h264_norm_shift[512]; |
|
| 39 |
+extern uint8_t ff_h264_mlps_state[4*64]; |
|
| 40 |
+extern uint8_t ff_h264_lps_range[4*2*64]; ///< rangeTabLPS |
|
| 41 |
+ |
|
| 42 |
+static void refill(CABACContext *c){
|
|
| 43 |
+#if CABAC_BITS == 16 |
|
| 44 |
+ c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); |
|
| 45 |
+#else |
|
| 46 |
+ c->low+= c->bytestream[0]<<1; |
|
| 47 |
+#endif |
|
| 48 |
+ c->low -= CABAC_MASK; |
|
| 49 |
+ c->bytestream+= CABAC_BITS/8; |
|
| 50 |
+} |
|
| 51 |
+ |
|
| 52 |
+static inline void renorm_cabac_decoder_once(CABACContext *c){
|
|
| 53 |
+ int shift= (uint32_t)(c->range - 0x100)>>31; |
|
| 54 |
+ c->range<<= shift; |
|
| 55 |
+ c->low <<= shift; |
|
| 56 |
+ if(!(c->low & CABAC_MASK)) |
|
| 57 |
+ refill(c); |
|
| 58 |
+} |
|
| 59 |
+ |
|
| 60 |
+#ifndef get_cabac_inline |
|
| 61 |
+static void refill2(CABACContext *c){
|
|
| 62 |
+ int i, x; |
|
| 63 |
+ |
|
| 64 |
+ x= c->low ^ (c->low-1); |
|
| 65 |
+ i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; |
|
| 66 |
+ |
|
| 67 |
+ x= -CABAC_MASK; |
|
| 68 |
+ |
|
| 69 |
+#if CABAC_BITS == 16 |
|
| 70 |
+ x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); |
|
| 71 |
+#else |
|
| 72 |
+ x+= c->bytestream[0]<<1; |
|
| 73 |
+#endif |
|
| 74 |
+ |
|
| 75 |
+ c->low += x<<i; |
|
| 76 |
+ c->bytestream+= CABAC_BITS/8; |
|
| 77 |
+} |
|
| 78 |
+ |
|
| 79 |
+static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){
|
|
| 80 |
+ int s = *state; |
|
| 81 |
+ int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; |
|
| 82 |
+ int bit, lps_mask; |
|
| 83 |
+ |
|
| 84 |
+ c->range -= RangeLPS; |
|
| 85 |
+ lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; |
|
| 86 |
+ |
|
| 87 |
+ c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; |
|
| 88 |
+ c->range += (RangeLPS - c->range) & lps_mask; |
|
| 89 |
+ |
|
| 90 |
+ s^=lps_mask; |
|
| 91 |
+ *state= (ff_h264_mlps_state+128)[s]; |
|
| 92 |
+ bit= s&1; |
|
| 93 |
+ |
|
| 94 |
+ lps_mask= ff_h264_norm_shift[c->range]; |
|
| 95 |
+ c->range<<= lps_mask; |
|
| 96 |
+ c->low <<= lps_mask; |
|
| 97 |
+ if(!(c->low & CABAC_MASK)) |
|
| 98 |
+ refill2(c); |
|
| 99 |
+ return bit; |
|
| 100 |
+} |
|
| 101 |
+#endif |
|
| 102 |
+ |
|
| 103 |
+static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){
|
|
| 104 |
+ return get_cabac_inline(c,state); |
|
| 105 |
+} |
|
| 106 |
+ |
|
| 107 |
+static int av_unused get_cabac(CABACContext *c, uint8_t * const state){
|
|
| 108 |
+ return get_cabac_inline(c,state); |
|
| 109 |
+} |
|
| 110 |
+ |
|
| 111 |
+static int av_unused get_cabac_bypass(CABACContext *c){
|
|
| 112 |
+ int range; |
|
| 113 |
+ c->low += c->low; |
|
| 114 |
+ |
|
| 115 |
+ if(!(c->low & CABAC_MASK)) |
|
| 116 |
+ refill(c); |
|
| 117 |
+ |
|
| 118 |
+ range= c->range<<(CABAC_BITS+1); |
|
| 119 |
+ if(c->low < range){
|
|
| 120 |
+ return 0; |
|
| 121 |
+ }else{
|
|
| 122 |
+ c->low -= range; |
|
| 123 |
+ return 1; |
|
| 124 |
+ } |
|
| 125 |
+} |
|
| 126 |
+ |
|
| 127 |
+ |
|
| 128 |
+#ifndef get_cabac_bypass_sign |
|
| 129 |
+static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){
|
|
| 130 |
+ int range, mask; |
|
| 131 |
+ c->low += c->low; |
|
| 132 |
+ |
|
| 133 |
+ if(!(c->low & CABAC_MASK)) |
|
| 134 |
+ refill(c); |
|
| 135 |
+ |
|
| 136 |
+ range= c->range<<(CABAC_BITS+1); |
|
| 137 |
+ c->low -= range; |
|
| 138 |
+ mask= c->low >> 31; |
|
| 139 |
+ range &= mask; |
|
| 140 |
+ c->low += range; |
|
| 141 |
+ return (val^mask)-mask; |
|
| 142 |
+} |
|
| 143 |
+#endif |
|
| 144 |
+ |
|
| 145 |
+/** |
|
| 146 |
+ * |
|
| 147 |
+ * @return the number of bytes read or 0 if no end |
|
| 148 |
+ */ |
|
| 149 |
+static int av_unused get_cabac_terminate(CABACContext *c){
|
|
| 150 |
+ c->range -= 2; |
|
| 151 |
+ if(c->low < c->range<<(CABAC_BITS+1)){
|
|
| 152 |
+ renorm_cabac_decoder_once(c); |
|
| 153 |
+ return 0; |
|
| 154 |
+ }else{
|
|
| 155 |
+ return c->bytestream - c->bytestream_start; |
|
| 156 |
+ } |
|
| 157 |
+} |
|
| 158 |
+ |
|
| 159 |
+#endif /* AVCODEC_CABAC_FUNCTIONS_H */ |
| ... | ... |
@@ -30,6 +30,8 @@ |
| 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 @@ |
| 43 | 43 |
#include "vdpau_internal.h" |
| 44 | 44 |
#include "libavutil/avassert.h" |
| 45 | 45 |
|
| 46 |
-#include "cabac.h" |
|
| 47 |
- |
|
| 48 | 46 |
//#undef NDEBUG |
| 49 | 47 |
#include <assert.h> |
| 50 | 48 |
|
| ... | ... |
@@ -28,6 +28,9 @@ |
| 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 @@ |
| 36 | 36 |
#include "h264_mvpred.h" |
| 37 | 37 |
#include "golomb.h" |
| 38 | 38 |
|
| 39 |
-#include "cabac.h" |
|
| 40 | 39 |
#if ARCH_X86 |
| 41 | 40 |
#include "x86/h264_i386.h" |
| 42 | 41 |
#endif |
| ... | ... |
@@ -183,6 +183,25 @@ void rgb16tobgr32(const uint8_t *src, uint8_t *dst, int src_size) |
| 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); |
| 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) |
| 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 |
| 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[], |
| 428 | 428 |
if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) || |
| 429 | 429 |
(isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
|
| 430 | 430 |
switch (srcId | (dstId << 16)) {
|
| 431 |
+ case 0x000F000C: conv = rgb12to15; break; |
|
| 431 | 432 |
case 0x000F0010: conv = rgb16to15; break; |
| 432 | 433 |
case 0x000F0018: conv = rgb24to15; break; |
| 433 | 434 |
case 0x000F0020: conv = rgb32to15; break; |
| ... | ... |
@@ -463,6 +469,21 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], |
| 463 | 463 |
} |
| 464 | 464 |
} |
| 465 | 465 |
|
| 466 |
+ return conv; |
|
| 467 |
+} |
|
| 468 |
+ |
|
| 469 |
+/* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
|
|
| 470 |
+static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], |
|
| 471 |
+ int srcSliceY, int srcSliceH, uint8_t *dst[], |
|
| 472 |
+ int dstStride[]) |
|
| 473 |
+ |
|
| 474 |
+{
|
|
| 475 |
+ const enum PixelFormat srcFormat = c->srcFormat; |
|
| 476 |
+ const enum PixelFormat dstFormat = c->dstFormat; |
|
| 477 |
+ const int srcBpp = (c->srcFormatBpp + 7) >> 3; |
|
| 478 |
+ const int dstBpp = (c->dstFormatBpp + 7) >> 3; |
|
| 479 |
+ rgbConvFn conv = findRgbConvFn(c); |
|
| 480 |
+ |
|
| 466 | 481 |
if (!conv) {
|
| 467 | 482 |
av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n", |
| 468 | 483 |
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[], |
| 694 | 694 |
} else {
|
| 695 | 695 |
if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) |
| 696 | 696 |
length *= 2; |
| 697 |
+ else if (!av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1) |
|
| 698 |
+ length >>= 3; // monowhite/black |
|
| 697 | 699 |
for (i = 0; i < height; i++) {
|
| 698 | 700 |
memcpy(dstPtr, srcPtr, length); |
| 699 | 701 |
srcPtr += srcStride[plane]; |
| ... | ... |
@@ -748,24 +771,8 @@ void ff_get_unscaled_swscale(SwsContext *c) |
| 748 | 748 |
c->swScale = bgr24ToYv12Wrapper; |
| 749 | 749 |
|
| 750 | 750 |
/* 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 |
- ) |
|
| 751 |
+ if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c) |
|
| 752 |
+ && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)))) |
|
| 769 | 753 |
c->swScale= rgbToRgbWrapper; |
| 770 | 754 |
|
| 771 | 755 |
#define isByteRGB(f) (\ |
| ... | ... |
@@ -30,6 +30,33 @@ fate-sunraster-24bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-raw. |
| 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 |