This duplicates the function fillPlane().
| ... | ... |
@@ -69,14 +69,6 @@ untested special converters |
| 69 | 69 |
|
| 70 | 70 |
#define DITHER1XBPP |
| 71 | 71 |
|
| 72 |
-#define isPacked(x) ( \ |
|
| 73 |
- (x)==PIX_FMT_PAL8 \ |
|
| 74 |
- || (x)==PIX_FMT_YUYV422 \ |
|
| 75 |
- || (x)==PIX_FMT_UYVY422 \ |
|
| 76 |
- || (x)==PIX_FMT_Y400A \ |
|
| 77 |
- || isAnyRGB(x) \ |
|
| 78 |
- ) |
|
| 79 |
- |
|
| 80 | 72 |
#define RGB2YUV_SHIFT 15 |
| 81 | 73 |
#define BY ( (int)(0.114*219/255*(1<<RGB2YUV_SHIFT)+0.5)) |
| 82 | 74 |
#define BV (-(int)(0.081*224/255*(1<<RGB2YUV_SHIFT)+0.5)) |
| ... | ... |
@@ -2096,834 +2088,3 @@ SwsFunc ff_getSwsFunc(SwsContext *c) |
| 2096 | 2096 |
|
| 2097 | 2097 |
return swScale; |
| 2098 | 2098 |
} |
| 2099 |
- |
|
| 2100 |
-static void copyPlane(const uint8_t *src, int srcStride, |
|
| 2101 |
- int srcSliceY, int srcSliceH, int width, |
|
| 2102 |
- uint8_t *dst, int dstStride) |
|
| 2103 |
-{
|
|
| 2104 |
- dst += dstStride * srcSliceY; |
|
| 2105 |
- if (dstStride == srcStride && srcStride > 0) {
|
|
| 2106 |
- memcpy(dst, src, srcSliceH * dstStride); |
|
| 2107 |
- } else {
|
|
| 2108 |
- int i; |
|
| 2109 |
- for (i=0; i<srcSliceH; i++) {
|
|
| 2110 |
- memcpy(dst, src, width); |
|
| 2111 |
- src += srcStride; |
|
| 2112 |
- dst += dstStride; |
|
| 2113 |
- } |
|
| 2114 |
- } |
|
| 2115 |
-} |
|
| 2116 |
- |
|
| 2117 |
-static int planarToNv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2118 |
- int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 2119 |
-{
|
|
| 2120 |
- uint8_t *dst = dstParam[1] + dstStride[1]*srcSliceY/2; |
|
| 2121 |
- |
|
| 2122 |
- copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW, |
|
| 2123 |
- dstParam[0], dstStride[0]); |
|
| 2124 |
- |
|
| 2125 |
- if (c->dstFormat == PIX_FMT_NV12) |
|
| 2126 |
- interleaveBytes(src[1], src[2], dst, c->srcW/2, srcSliceH/2, srcStride[1], srcStride[2], dstStride[0]); |
|
| 2127 |
- else |
|
| 2128 |
- interleaveBytes(src[2], src[1], dst, c->srcW/2, srcSliceH/2, srcStride[2], srcStride[1], dstStride[0]); |
|
| 2129 |
- |
|
| 2130 |
- return srcSliceH; |
|
| 2131 |
-} |
|
| 2132 |
- |
|
| 2133 |
-static int planarToYuy2Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2134 |
- int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 2135 |
-{
|
|
| 2136 |
- uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 2137 |
- |
|
| 2138 |
- yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]); |
|
| 2139 |
- |
|
| 2140 |
- return srcSliceH; |
|
| 2141 |
-} |
|
| 2142 |
- |
|
| 2143 |
-static int planarToUyvyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2144 |
- int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 2145 |
-{
|
|
| 2146 |
- uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 2147 |
- |
|
| 2148 |
- yv12touyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]); |
|
| 2149 |
- |
|
| 2150 |
- return srcSliceH; |
|
| 2151 |
-} |
|
| 2152 |
- |
|
| 2153 |
-static int yuv422pToYuy2Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2154 |
- int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 2155 |
-{
|
|
| 2156 |
- uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 2157 |
- |
|
| 2158 |
- yuv422ptoyuy2(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]); |
|
| 2159 |
- |
|
| 2160 |
- return srcSliceH; |
|
| 2161 |
-} |
|
| 2162 |
- |
|
| 2163 |
-static int yuv422pToUyvyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2164 |
- int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 2165 |
-{
|
|
| 2166 |
- uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 2167 |
- |
|
| 2168 |
- yuv422ptouyvy(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]); |
|
| 2169 |
- |
|
| 2170 |
- return srcSliceH; |
|
| 2171 |
-} |
|
| 2172 |
- |
|
| 2173 |
-static int yuyvToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2174 |
- int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 2175 |
-{
|
|
| 2176 |
- uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 2177 |
- uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2; |
|
| 2178 |
- uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2; |
|
| 2179 |
- |
|
| 2180 |
- yuyvtoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); |
|
| 2181 |
- |
|
| 2182 |
- if (dstParam[3]) |
|
| 2183 |
- fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); |
|
| 2184 |
- |
|
| 2185 |
- return srcSliceH; |
|
| 2186 |
-} |
|
| 2187 |
- |
|
| 2188 |
-static int yuyvToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2189 |
- int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 2190 |
-{
|
|
| 2191 |
- uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 2192 |
- uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY; |
|
| 2193 |
- uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY; |
|
| 2194 |
- |
|
| 2195 |
- yuyvtoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); |
|
| 2196 |
- |
|
| 2197 |
- return srcSliceH; |
|
| 2198 |
-} |
|
| 2199 |
- |
|
| 2200 |
-static int uyvyToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2201 |
- int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 2202 |
-{
|
|
| 2203 |
- uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 2204 |
- uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2; |
|
| 2205 |
- uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2; |
|
| 2206 |
- |
|
| 2207 |
- uyvytoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); |
|
| 2208 |
- |
|
| 2209 |
- if (dstParam[3]) |
|
| 2210 |
- fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); |
|
| 2211 |
- |
|
| 2212 |
- return srcSliceH; |
|
| 2213 |
-} |
|
| 2214 |
- |
|
| 2215 |
-static int uyvyToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2216 |
- int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 2217 |
-{
|
|
| 2218 |
- uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 2219 |
- uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY; |
|
| 2220 |
- uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY; |
|
| 2221 |
- |
|
| 2222 |
- uyvytoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); |
|
| 2223 |
- |
|
| 2224 |
- return srcSliceH; |
|
| 2225 |
-} |
|
| 2226 |
- |
|
| 2227 |
-static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) |
|
| 2228 |
-{
|
|
| 2229 |
- int i; |
|
| 2230 |
- for (i=0; i<num_pixels; i++) |
|
| 2231 |
- ((uint32_t *) dst)[i] = ((const uint32_t *)palette)[src[i<<1]] | (src[(i<<1)+1] << 24); |
|
| 2232 |
-} |
|
| 2233 |
- |
|
| 2234 |
-static void gray8aToPacked32_1(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) |
|
| 2235 |
-{
|
|
| 2236 |
- int i; |
|
| 2237 |
- |
|
| 2238 |
- for (i=0; i<num_pixels; i++) |
|
| 2239 |
- ((uint32_t *) dst)[i] = ((const uint32_t *)palette)[src[i<<1]] | src[(i<<1)+1]; |
|
| 2240 |
-} |
|
| 2241 |
- |
|
| 2242 |
-static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) |
|
| 2243 |
-{
|
|
| 2244 |
- int i; |
|
| 2245 |
- |
|
| 2246 |
- for (i=0; i<num_pixels; i++) {
|
|
| 2247 |
- //FIXME slow? |
|
| 2248 |
- dst[0]= palette[src[i<<1]*4+0]; |
|
| 2249 |
- dst[1]= palette[src[i<<1]*4+1]; |
|
| 2250 |
- dst[2]= palette[src[i<<1]*4+2]; |
|
| 2251 |
- dst+= 3; |
|
| 2252 |
- } |
|
| 2253 |
-} |
|
| 2254 |
- |
|
| 2255 |
-static int palToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2256 |
- int srcSliceH, uint8_t* dst[], int dstStride[]) |
|
| 2257 |
-{
|
|
| 2258 |
- const enum PixelFormat srcFormat= c->srcFormat; |
|
| 2259 |
- const enum PixelFormat dstFormat= c->dstFormat; |
|
| 2260 |
- void (*conv)(const uint8_t *src, uint8_t *dst, int num_pixels, |
|
| 2261 |
- const uint8_t *palette)=NULL; |
|
| 2262 |
- int i; |
|
| 2263 |
- uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY; |
|
| 2264 |
- const uint8_t *srcPtr= src[0]; |
|
| 2265 |
- |
|
| 2266 |
- if (srcFormat == PIX_FMT_Y400A) {
|
|
| 2267 |
- switch (dstFormat) {
|
|
| 2268 |
- case PIX_FMT_RGB32 : conv = gray8aToPacked32; break; |
|
| 2269 |
- case PIX_FMT_BGR32 : conv = gray8aToPacked32; break; |
|
| 2270 |
- case PIX_FMT_BGR32_1: conv = gray8aToPacked32_1; break; |
|
| 2271 |
- case PIX_FMT_RGB32_1: conv = gray8aToPacked32_1; break; |
|
| 2272 |
- case PIX_FMT_RGB24 : conv = gray8aToPacked24; break; |
|
| 2273 |
- case PIX_FMT_BGR24 : conv = gray8aToPacked24; break; |
|
| 2274 |
- } |
|
| 2275 |
- } else if (usePal(srcFormat)) {
|
|
| 2276 |
- switch (dstFormat) {
|
|
| 2277 |
- case PIX_FMT_RGB32 : conv = sws_convertPalette8ToPacked32; break; |
|
| 2278 |
- case PIX_FMT_BGR32 : conv = sws_convertPalette8ToPacked32; break; |
|
| 2279 |
- case PIX_FMT_BGR32_1: conv = sws_convertPalette8ToPacked32; break; |
|
| 2280 |
- case PIX_FMT_RGB32_1: conv = sws_convertPalette8ToPacked32; break; |
|
| 2281 |
- case PIX_FMT_RGB24 : conv = sws_convertPalette8ToPacked24; break; |
|
| 2282 |
- case PIX_FMT_BGR24 : conv = sws_convertPalette8ToPacked24; break; |
|
| 2283 |
- } |
|
| 2284 |
- } |
|
| 2285 |
- |
|
| 2286 |
- if (!conv) |
|
| 2287 |
- av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n", |
|
| 2288 |
- sws_format_name(srcFormat), sws_format_name(dstFormat)); |
|
| 2289 |
- else {
|
|
| 2290 |
- for (i=0; i<srcSliceH; i++) {
|
|
| 2291 |
- conv(srcPtr, dstPtr, c->srcW, (uint8_t *) c->pal_rgb); |
|
| 2292 |
- srcPtr+= srcStride[0]; |
|
| 2293 |
- dstPtr+= dstStride[0]; |
|
| 2294 |
- } |
|
| 2295 |
- } |
|
| 2296 |
- |
|
| 2297 |
- return srcSliceH; |
|
| 2298 |
-} |
|
| 2299 |
- |
|
| 2300 |
-#define isRGBA32(x) ( \ |
|
| 2301 |
- (x) == PIX_FMT_ARGB \ |
|
| 2302 |
- || (x) == PIX_FMT_RGBA \ |
|
| 2303 |
- || (x) == PIX_FMT_BGRA \ |
|
| 2304 |
- || (x) == PIX_FMT_ABGR \ |
|
| 2305 |
- ) |
|
| 2306 |
- |
|
| 2307 |
-/* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
|
|
| 2308 |
-static int rgbToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2309 |
- int srcSliceH, uint8_t* dst[], int dstStride[]) |
|
| 2310 |
-{
|
|
| 2311 |
- const enum PixelFormat srcFormat= c->srcFormat; |
|
| 2312 |
- const enum PixelFormat dstFormat= c->dstFormat; |
|
| 2313 |
- const int srcBpp= (c->srcFormatBpp + 7) >> 3; |
|
| 2314 |
- const int dstBpp= (c->dstFormatBpp + 7) >> 3; |
|
| 2315 |
- const int srcId= c->srcFormatBpp >> 2; /* 1:0, 4:1, 8:2, 15:3, 16:4, 24:6, 32:8 */ |
|
| 2316 |
- const int dstId= c->dstFormatBpp >> 2; |
|
| 2317 |
- void (*conv)(const uint8_t *src, uint8_t *dst, int src_size)=NULL; |
|
| 2318 |
- |
|
| 2319 |
-#define CONV_IS(src, dst) (srcFormat == PIX_FMT_##src && dstFormat == PIX_FMT_##dst) |
|
| 2320 |
- |
|
| 2321 |
- if (isRGBA32(srcFormat) && isRGBA32(dstFormat)) {
|
|
| 2322 |
- if ( CONV_IS(ABGR, RGBA) |
|
| 2323 |
- || CONV_IS(ARGB, BGRA) |
|
| 2324 |
- || CONV_IS(BGRA, ARGB) |
|
| 2325 |
- || CONV_IS(RGBA, ABGR)) conv = shuffle_bytes_3210; |
|
| 2326 |
- else if (CONV_IS(ABGR, ARGB) |
|
| 2327 |
- || CONV_IS(ARGB, ABGR)) conv = shuffle_bytes_0321; |
|
| 2328 |
- else if (CONV_IS(ABGR, BGRA) |
|
| 2329 |
- || CONV_IS(ARGB, RGBA)) conv = shuffle_bytes_1230; |
|
| 2330 |
- else if (CONV_IS(BGRA, RGBA) |
|
| 2331 |
- || CONV_IS(RGBA, BGRA)) conv = shuffle_bytes_2103; |
|
| 2332 |
- else if (CONV_IS(BGRA, ABGR) |
|
| 2333 |
- || CONV_IS(RGBA, ARGB)) conv = shuffle_bytes_3012; |
|
| 2334 |
- } else |
|
| 2335 |
- /* BGR -> BGR */ |
|
| 2336 |
- if ( (isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) |
|
| 2337 |
- || (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
|
|
| 2338 |
- switch(srcId | (dstId<<4)) {
|
|
| 2339 |
- case 0x34: conv= rgb16to15; break; |
|
| 2340 |
- case 0x36: conv= rgb24to15; break; |
|
| 2341 |
- case 0x38: conv= rgb32to15; break; |
|
| 2342 |
- case 0x43: conv= rgb15to16; break; |
|
| 2343 |
- case 0x46: conv= rgb24to16; break; |
|
| 2344 |
- case 0x48: conv= rgb32to16; break; |
|
| 2345 |
- case 0x63: conv= rgb15to24; break; |
|
| 2346 |
- case 0x64: conv= rgb16to24; break; |
|
| 2347 |
- case 0x68: conv= rgb32to24; break; |
|
| 2348 |
- case 0x83: conv= rgb15to32; break; |
|
| 2349 |
- case 0x84: conv= rgb16to32; break; |
|
| 2350 |
- case 0x86: conv= rgb24to32; break; |
|
| 2351 |
- } |
|
| 2352 |
- } else if ( (isBGRinInt(srcFormat) && isRGBinInt(dstFormat)) |
|
| 2353 |
- || (isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) {
|
|
| 2354 |
- switch(srcId | (dstId<<4)) {
|
|
| 2355 |
- case 0x33: conv= rgb15tobgr15; break; |
|
| 2356 |
- case 0x34: conv= rgb16tobgr15; break; |
|
| 2357 |
- case 0x36: conv= rgb24tobgr15; break; |
|
| 2358 |
- case 0x38: conv= rgb32tobgr15; break; |
|
| 2359 |
- case 0x43: conv= rgb15tobgr16; break; |
|
| 2360 |
- case 0x44: conv= rgb16tobgr16; break; |
|
| 2361 |
- case 0x46: conv= rgb24tobgr16; break; |
|
| 2362 |
- case 0x48: conv= rgb32tobgr16; break; |
|
| 2363 |
- case 0x63: conv= rgb15tobgr24; break; |
|
| 2364 |
- case 0x64: conv= rgb16tobgr24; break; |
|
| 2365 |
- case 0x66: conv= rgb24tobgr24; break; |
|
| 2366 |
- case 0x68: conv= rgb32tobgr24; break; |
|
| 2367 |
- case 0x83: conv= rgb15tobgr32; break; |
|
| 2368 |
- case 0x84: conv= rgb16tobgr32; break; |
|
| 2369 |
- case 0x86: conv= rgb24tobgr32; break; |
|
| 2370 |
- } |
|
| 2371 |
- } |
|
| 2372 |
- |
|
| 2373 |
- if (!conv) {
|
|
| 2374 |
- av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n", |
|
| 2375 |
- sws_format_name(srcFormat), sws_format_name(dstFormat)); |
|
| 2376 |
- } else {
|
|
| 2377 |
- const uint8_t *srcPtr= src[0]; |
|
| 2378 |
- uint8_t *dstPtr= dst[0]; |
|
| 2379 |
- if ((srcFormat == PIX_FMT_RGB32_1 || srcFormat == PIX_FMT_BGR32_1) && !isRGBA32(dstFormat)) |
|
| 2380 |
- srcPtr += ALT32_CORR; |
|
| 2381 |
- |
|
| 2382 |
- if ((dstFormat == PIX_FMT_RGB32_1 || dstFormat == PIX_FMT_BGR32_1) && !isRGBA32(srcFormat)) |
|
| 2383 |
- dstPtr += ALT32_CORR; |
|
| 2384 |
- |
|
| 2385 |
- if (dstStride[0]*srcBpp == srcStride[0]*dstBpp && srcStride[0] > 0) |
|
| 2386 |
- conv(srcPtr, dstPtr + dstStride[0]*srcSliceY, srcSliceH*srcStride[0]); |
|
| 2387 |
- else {
|
|
| 2388 |
- int i; |
|
| 2389 |
- dstPtr += dstStride[0]*srcSliceY; |
|
| 2390 |
- |
|
| 2391 |
- for (i=0; i<srcSliceH; i++) {
|
|
| 2392 |
- conv(srcPtr, dstPtr, c->srcW*srcBpp); |
|
| 2393 |
- srcPtr+= srcStride[0]; |
|
| 2394 |
- dstPtr+= dstStride[0]; |
|
| 2395 |
- } |
|
| 2396 |
- } |
|
| 2397 |
- } |
|
| 2398 |
- return srcSliceH; |
|
| 2399 |
-} |
|
| 2400 |
- |
|
| 2401 |
-static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2402 |
- int srcSliceH, uint8_t* dst[], int dstStride[]) |
|
| 2403 |
-{
|
|
| 2404 |
- rgb24toyv12( |
|
| 2405 |
- src[0], |
|
| 2406 |
- dst[0]+ srcSliceY *dstStride[0], |
|
| 2407 |
- dst[1]+(srcSliceY>>1)*dstStride[1], |
|
| 2408 |
- dst[2]+(srcSliceY>>1)*dstStride[2], |
|
| 2409 |
- c->srcW, srcSliceH, |
|
| 2410 |
- dstStride[0], dstStride[1], srcStride[0]); |
|
| 2411 |
- if (dst[3]) |
|
| 2412 |
- fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); |
|
| 2413 |
- return srcSliceH; |
|
| 2414 |
-} |
|
| 2415 |
- |
|
| 2416 |
-static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2417 |
- int srcSliceH, uint8_t* dst[], int dstStride[]) |
|
| 2418 |
-{
|
|
| 2419 |
- copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW, |
|
| 2420 |
- dst[0], dstStride[0]); |
|
| 2421 |
- |
|
| 2422 |
- planar2x(src[1], dst[1] + dstStride[1]*(srcSliceY >> 1), c->chrSrcW, |
|
| 2423 |
- srcSliceH >> 2, srcStride[1], dstStride[1]); |
|
| 2424 |
- planar2x(src[2], dst[2] + dstStride[2]*(srcSliceY >> 1), c->chrSrcW, |
|
| 2425 |
- srcSliceH >> 2, srcStride[2], dstStride[2]); |
|
| 2426 |
- if (dst[3]) |
|
| 2427 |
- fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); |
|
| 2428 |
- return srcSliceH; |
|
| 2429 |
-} |
|
| 2430 |
- |
|
| 2431 |
-/* unscaled copy like stuff (assumes nearly identical formats) */ |
|
| 2432 |
-static int packedCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2433 |
- int srcSliceH, uint8_t* dst[], int dstStride[]) |
|
| 2434 |
-{
|
|
| 2435 |
- if (dstStride[0]==srcStride[0] && srcStride[0] > 0) |
|
| 2436 |
- memcpy(dst[0] + dstStride[0]*srcSliceY, src[0], srcSliceH*dstStride[0]); |
|
| 2437 |
- else {
|
|
| 2438 |
- int i; |
|
| 2439 |
- const uint8_t *srcPtr= src[0]; |
|
| 2440 |
- uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY; |
|
| 2441 |
- int length=0; |
|
| 2442 |
- |
|
| 2443 |
- /* universal length finder */ |
|
| 2444 |
- while(length+c->srcW <= FFABS(dstStride[0]) |
|
| 2445 |
- && length+c->srcW <= FFABS(srcStride[0])) length+= c->srcW; |
|
| 2446 |
- assert(length!=0); |
|
| 2447 |
- |
|
| 2448 |
- for (i=0; i<srcSliceH; i++) {
|
|
| 2449 |
- memcpy(dstPtr, srcPtr, length); |
|
| 2450 |
- srcPtr+= srcStride[0]; |
|
| 2451 |
- dstPtr+= dstStride[0]; |
|
| 2452 |
- } |
|
| 2453 |
- } |
|
| 2454 |
- return srcSliceH; |
|
| 2455 |
-} |
|
| 2456 |
- |
|
| 2457 |
-static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 2458 |
- int srcSliceH, uint8_t* dst[], int dstStride[]) |
|
| 2459 |
-{
|
|
| 2460 |
- int plane, i, j; |
|
| 2461 |
- for (plane=0; plane<4; plane++) {
|
|
| 2462 |
- int length= (plane==0 || plane==3) ? c->srcW : -((-c->srcW )>>c->chrDstHSubSample); |
|
| 2463 |
- int y= (plane==0 || plane==3) ? srcSliceY: -((-srcSliceY)>>c->chrDstVSubSample); |
|
| 2464 |
- int height= (plane==0 || plane==3) ? srcSliceH: -((-srcSliceH)>>c->chrDstVSubSample); |
|
| 2465 |
- const uint8_t *srcPtr= src[plane]; |
|
| 2466 |
- uint8_t *dstPtr= dst[plane] + dstStride[plane]*y; |
|
| 2467 |
- |
|
| 2468 |
- if (!dst[plane]) continue; |
|
| 2469 |
- // ignore palette for GRAY8 |
|
| 2470 |
- if (plane == 1 && !dst[2]) continue; |
|
| 2471 |
- if (!src[plane] || (plane == 1 && !src[2])) {
|
|
| 2472 |
- if(is16BPS(c->dstFormat)) |
|
| 2473 |
- length*=2; |
|
| 2474 |
- fillPlane(dst[plane], dstStride[plane], length, height, y, (plane==3) ? 255 : 128); |
|
| 2475 |
- } else {
|
|
| 2476 |
- if(is9_OR_10BPS(c->srcFormat)) {
|
|
| 2477 |
- const int src_depth = av_pix_fmt_descriptors[c->srcFormat].comp[plane].depth_minus1+1; |
|
| 2478 |
- const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1+1; |
|
| 2479 |
- const uint16_t *srcPtr2 = (const uint16_t*)srcPtr; |
|
| 2480 |
- |
|
| 2481 |
- if (is16BPS(c->dstFormat)) {
|
|
| 2482 |
- uint16_t *dstPtr2 = (uint16_t*)dstPtr; |
|
| 2483 |
-#define COPY9_OR_10TO16(rfunc, wfunc) \ |
|
| 2484 |
- for (i = 0; i < height; i++) { \
|
|
| 2485 |
- for (j = 0; j < length; j++) { \
|
|
| 2486 |
- int srcpx = rfunc(&srcPtr2[j]); \ |
|
| 2487 |
- wfunc(&dstPtr2[j], (srcpx<<(16-src_depth)) | (srcpx>>(2*src_depth-16))); \ |
|
| 2488 |
- } \ |
|
| 2489 |
- dstPtr2 += dstStride[plane]/2; \ |
|
| 2490 |
- srcPtr2 += srcStride[plane]/2; \ |
|
| 2491 |
- } |
|
| 2492 |
- if (isBE(c->dstFormat)) {
|
|
| 2493 |
- if (isBE(c->srcFormat)) {
|
|
| 2494 |
- COPY9_OR_10TO16(AV_RB16, AV_WB16); |
|
| 2495 |
- } else {
|
|
| 2496 |
- COPY9_OR_10TO16(AV_RL16, AV_WB16); |
|
| 2497 |
- } |
|
| 2498 |
- } else {
|
|
| 2499 |
- if (isBE(c->srcFormat)) {
|
|
| 2500 |
- COPY9_OR_10TO16(AV_RB16, AV_WL16); |
|
| 2501 |
- } else {
|
|
| 2502 |
- COPY9_OR_10TO16(AV_RL16, AV_WL16); |
|
| 2503 |
- } |
|
| 2504 |
- } |
|
| 2505 |
- } else if (is9_OR_10BPS(c->dstFormat)) {
|
|
| 2506 |
- uint16_t *dstPtr2 = (uint16_t*)dstPtr; |
|
| 2507 |
-#define COPY9_OR_10TO9_OR_10(loop) \ |
|
| 2508 |
- for (i = 0; i < height; i++) { \
|
|
| 2509 |
- for (j = 0; j < length; j++) { \
|
|
| 2510 |
- loop; \ |
|
| 2511 |
- } \ |
|
| 2512 |
- dstPtr2 += dstStride[plane]/2; \ |
|
| 2513 |
- srcPtr2 += srcStride[plane]/2; \ |
|
| 2514 |
- } |
|
| 2515 |
-#define COPY9_OR_10TO9_OR_10_2(rfunc, wfunc) \ |
|
| 2516 |
- if (dst_depth > src_depth) { \
|
|
| 2517 |
- COPY9_OR_10TO9_OR_10(int srcpx = rfunc(&srcPtr2[j]); \ |
|
| 2518 |
- wfunc(&dstPtr2[j], (srcpx << 1) | (srcpx >> 9))); \ |
|
| 2519 |
- } else if (dst_depth < src_depth) { \
|
|
| 2520 |
- COPY9_OR_10TO9_OR_10(wfunc(&dstPtr2[j], rfunc(&srcPtr2[j]) >> 1)); \ |
|
| 2521 |
- } else { \
|
|
| 2522 |
- COPY9_OR_10TO9_OR_10(wfunc(&dstPtr2[j], rfunc(&srcPtr2[j]))); \ |
|
| 2523 |
- } |
|
| 2524 |
- if (isBE(c->dstFormat)) {
|
|
| 2525 |
- if (isBE(c->srcFormat)) {
|
|
| 2526 |
- COPY9_OR_10TO9_OR_10_2(AV_RB16, AV_WB16); |
|
| 2527 |
- } else {
|
|
| 2528 |
- COPY9_OR_10TO9_OR_10_2(AV_RL16, AV_WB16); |
|
| 2529 |
- } |
|
| 2530 |
- } else {
|
|
| 2531 |
- if (isBE(c->srcFormat)) {
|
|
| 2532 |
- COPY9_OR_10TO9_OR_10_2(AV_RB16, AV_WL16); |
|
| 2533 |
- } else {
|
|
| 2534 |
- COPY9_OR_10TO9_OR_10_2(AV_RL16, AV_WL16); |
|
| 2535 |
- } |
|
| 2536 |
- } |
|
| 2537 |
- } else {
|
|
| 2538 |
- // FIXME Maybe dither instead. |
|
| 2539 |
-#define COPY9_OR_10TO8(rfunc) \ |
|
| 2540 |
- for (i = 0; i < height; i++) { \
|
|
| 2541 |
- for (j = 0; j < length; j++) { \
|
|
| 2542 |
- dstPtr[j] = rfunc(&srcPtr2[j])>>(src_depth-8); \ |
|
| 2543 |
- } \ |
|
| 2544 |
- dstPtr += dstStride[plane]; \ |
|
| 2545 |
- srcPtr2 += srcStride[plane]/2; \ |
|
| 2546 |
- } |
|
| 2547 |
- if (isBE(c->srcFormat)) {
|
|
| 2548 |
- COPY9_OR_10TO8(AV_RB16); |
|
| 2549 |
- } else {
|
|
| 2550 |
- COPY9_OR_10TO8(AV_RL16); |
|
| 2551 |
- } |
|
| 2552 |
- } |
|
| 2553 |
- } else if(is9_OR_10BPS(c->dstFormat)) {
|
|
| 2554 |
- const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1+1; |
|
| 2555 |
- uint16_t *dstPtr2 = (uint16_t*)dstPtr; |
|
| 2556 |
- |
|
| 2557 |
- if (is16BPS(c->srcFormat)) {
|
|
| 2558 |
- const uint16_t *srcPtr2 = (const uint16_t*)srcPtr; |
|
| 2559 |
-#define COPY16TO9_OR_10(rfunc, wfunc) \ |
|
| 2560 |
- for (i = 0; i < height; i++) { \
|
|
| 2561 |
- for (j = 0; j < length; j++) { \
|
|
| 2562 |
- wfunc(&dstPtr2[j], rfunc(&srcPtr2[j])>>(16-dst_depth)); \ |
|
| 2563 |
- } \ |
|
| 2564 |
- dstPtr2 += dstStride[plane]/2; \ |
|
| 2565 |
- srcPtr2 += srcStride[plane]/2; \ |
|
| 2566 |
- } |
|
| 2567 |
- if (isBE(c->dstFormat)) {
|
|
| 2568 |
- if (isBE(c->srcFormat)) {
|
|
| 2569 |
- COPY16TO9_OR_10(AV_RB16, AV_WB16); |
|
| 2570 |
- } else {
|
|
| 2571 |
- COPY16TO9_OR_10(AV_RL16, AV_WB16); |
|
| 2572 |
- } |
|
| 2573 |
- } else {
|
|
| 2574 |
- if (isBE(c->srcFormat)) {
|
|
| 2575 |
- COPY16TO9_OR_10(AV_RB16, AV_WL16); |
|
| 2576 |
- } else {
|
|
| 2577 |
- COPY16TO9_OR_10(AV_RL16, AV_WL16); |
|
| 2578 |
- } |
|
| 2579 |
- } |
|
| 2580 |
- } else /* 8bit */ {
|
|
| 2581 |
-#define COPY8TO9_OR_10(wfunc) \ |
|
| 2582 |
- for (i = 0; i < height; i++) { \
|
|
| 2583 |
- for (j = 0; j < length; j++) { \
|
|
| 2584 |
- const int srcpx = srcPtr[j]; \ |
|
| 2585 |
- wfunc(&dstPtr2[j], (srcpx<<(dst_depth-8)) | (srcpx >> (16-dst_depth))); \ |
|
| 2586 |
- } \ |
|
| 2587 |
- dstPtr2 += dstStride[plane]/2; \ |
|
| 2588 |
- srcPtr += srcStride[plane]; \ |
|
| 2589 |
- } |
|
| 2590 |
- if (isBE(c->dstFormat)) {
|
|
| 2591 |
- COPY8TO9_OR_10(AV_WB16); |
|
| 2592 |
- } else {
|
|
| 2593 |
- COPY8TO9_OR_10(AV_WL16); |
|
| 2594 |
- } |
|
| 2595 |
- } |
|
| 2596 |
- } else if(is16BPS(c->srcFormat) && !is16BPS(c->dstFormat)) {
|
|
| 2597 |
- if (!isBE(c->srcFormat)) srcPtr++; |
|
| 2598 |
- for (i=0; i<height; i++) {
|
|
| 2599 |
- for (j=0; j<length; j++) dstPtr[j] = srcPtr[j<<1]; |
|
| 2600 |
- srcPtr+= srcStride[plane]; |
|
| 2601 |
- dstPtr+= dstStride[plane]; |
|
| 2602 |
- } |
|
| 2603 |
- } else if(!is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) {
|
|
| 2604 |
- for (i=0; i<height; i++) {
|
|
| 2605 |
- for (j=0; j<length; j++) {
|
|
| 2606 |
- dstPtr[ j<<1 ] = srcPtr[j]; |
|
| 2607 |
- dstPtr[(j<<1)+1] = srcPtr[j]; |
|
| 2608 |
- } |
|
| 2609 |
- srcPtr+= srcStride[plane]; |
|
| 2610 |
- dstPtr+= dstStride[plane]; |
|
| 2611 |
- } |
|
| 2612 |
- } else if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat) |
|
| 2613 |
- && isBE(c->srcFormat) != isBE(c->dstFormat)) {
|
|
| 2614 |
- |
|
| 2615 |
- for (i=0; i<height; i++) {
|
|
| 2616 |
- for (j=0; j<length; j++) |
|
| 2617 |
- ((uint16_t*)dstPtr)[j] = av_bswap16(((const uint16_t*)srcPtr)[j]); |
|
| 2618 |
- srcPtr+= srcStride[plane]; |
|
| 2619 |
- dstPtr+= dstStride[plane]; |
|
| 2620 |
- } |
|
| 2621 |
- } else if (dstStride[plane] == srcStride[plane] && |
|
| 2622 |
- srcStride[plane] > 0 && srcStride[plane] == length) {
|
|
| 2623 |
- memcpy(dst[plane] + dstStride[plane]*y, src[plane], |
|
| 2624 |
- height*dstStride[plane]); |
|
| 2625 |
- } else {
|
|
| 2626 |
- if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) |
|
| 2627 |
- length*=2; |
|
| 2628 |
- for (i=0; i<height; i++) {
|
|
| 2629 |
- memcpy(dstPtr, srcPtr, length); |
|
| 2630 |
- srcPtr+= srcStride[plane]; |
|
| 2631 |
- dstPtr+= dstStride[plane]; |
|
| 2632 |
- } |
|
| 2633 |
- } |
|
| 2634 |
- } |
|
| 2635 |
- } |
|
| 2636 |
- return srcSliceH; |
|
| 2637 |
-} |
|
| 2638 |
- |
|
| 2639 |
-void ff_get_unscaled_swscale(SwsContext *c) |
|
| 2640 |
-{
|
|
| 2641 |
- const enum PixelFormat srcFormat = c->srcFormat; |
|
| 2642 |
- const enum PixelFormat dstFormat = c->dstFormat; |
|
| 2643 |
- const int flags = c->flags; |
|
| 2644 |
- const int dstH = c->dstH; |
|
| 2645 |
- int needsDither; |
|
| 2646 |
- |
|
| 2647 |
- needsDither= isAnyRGB(dstFormat) |
|
| 2648 |
- && c->dstFormatBpp < 24 |
|
| 2649 |
- && (c->dstFormatBpp < c->srcFormatBpp || (!isAnyRGB(srcFormat))); |
|
| 2650 |
- |
|
| 2651 |
- /* yv12_to_nv12 */ |
|
| 2652 |
- if ((srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P) && (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21)) {
|
|
| 2653 |
- c->swScale= planarToNv12Wrapper; |
|
| 2654 |
- } |
|
| 2655 |
- /* yuv2bgr */ |
|
| 2656 |
- if ((srcFormat==PIX_FMT_YUV420P || srcFormat==PIX_FMT_YUV422P || srcFormat==PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) |
|
| 2657 |
- && !(flags & SWS_ACCURATE_RND) && !(dstH&1)) {
|
|
| 2658 |
- c->swScale= ff_yuv2rgb_get_func_ptr(c); |
|
| 2659 |
- } |
|
| 2660 |
- |
|
| 2661 |
- if (srcFormat==PIX_FMT_YUV410P && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_BITEXACT)) {
|
|
| 2662 |
- c->swScale= yvu9ToYv12Wrapper; |
|
| 2663 |
- } |
|
| 2664 |
- |
|
| 2665 |
- /* bgr24toYV12 */ |
|
| 2666 |
- if (srcFormat==PIX_FMT_BGR24 && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_ACCURATE_RND)) |
|
| 2667 |
- c->swScale= bgr24ToYv12Wrapper; |
|
| 2668 |
- |
|
| 2669 |
- /* RGB/BGR -> RGB/BGR (no dither needed forms) */ |
|
| 2670 |
- if ( isAnyRGB(srcFormat) |
|
| 2671 |
- && isAnyRGB(dstFormat) |
|
| 2672 |
- && srcFormat != PIX_FMT_BGR8 && dstFormat != PIX_FMT_BGR8 |
|
| 2673 |
- && srcFormat != PIX_FMT_RGB8 && dstFormat != PIX_FMT_RGB8 |
|
| 2674 |
- && srcFormat != PIX_FMT_BGR4 && dstFormat != PIX_FMT_BGR4 |
|
| 2675 |
- && srcFormat != PIX_FMT_RGB4 && dstFormat != PIX_FMT_RGB4 |
|
| 2676 |
- && srcFormat != PIX_FMT_BGR4_BYTE && dstFormat != PIX_FMT_BGR4_BYTE |
|
| 2677 |
- && srcFormat != PIX_FMT_RGB4_BYTE && dstFormat != PIX_FMT_RGB4_BYTE |
|
| 2678 |
- && srcFormat != PIX_FMT_MONOBLACK && dstFormat != PIX_FMT_MONOBLACK |
|
| 2679 |
- && srcFormat != PIX_FMT_MONOWHITE && dstFormat != PIX_FMT_MONOWHITE |
|
| 2680 |
- && srcFormat != PIX_FMT_RGB48LE && dstFormat != PIX_FMT_RGB48LE |
|
| 2681 |
- && srcFormat != PIX_FMT_RGB48BE && dstFormat != PIX_FMT_RGB48BE |
|
| 2682 |
- && srcFormat != PIX_FMT_BGR48LE && dstFormat != PIX_FMT_BGR48LE |
|
| 2683 |
- && srcFormat != PIX_FMT_BGR48BE && dstFormat != PIX_FMT_BGR48BE |
|
| 2684 |
- && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)))) |
|
| 2685 |
- c->swScale= rgbToRgbWrapper; |
|
| 2686 |
- |
|
| 2687 |
- if ((usePal(srcFormat) && ( |
|
| 2688 |
- dstFormat == PIX_FMT_RGB32 || |
|
| 2689 |
- dstFormat == PIX_FMT_RGB32_1 || |
|
| 2690 |
- dstFormat == PIX_FMT_RGB24 || |
|
| 2691 |
- dstFormat == PIX_FMT_BGR32 || |
|
| 2692 |
- dstFormat == PIX_FMT_BGR32_1 || |
|
| 2693 |
- dstFormat == PIX_FMT_BGR24))) |
|
| 2694 |
- c->swScale= palToRgbWrapper; |
|
| 2695 |
- |
|
| 2696 |
- if (srcFormat == PIX_FMT_YUV422P) {
|
|
| 2697 |
- if (dstFormat == PIX_FMT_YUYV422) |
|
| 2698 |
- c->swScale= yuv422pToYuy2Wrapper; |
|
| 2699 |
- else if (dstFormat == PIX_FMT_UYVY422) |
|
| 2700 |
- c->swScale= yuv422pToUyvyWrapper; |
|
| 2701 |
- } |
|
| 2702 |
- |
|
| 2703 |
- /* LQ converters if -sws 0 or -sws 4*/ |
|
| 2704 |
- if (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)) {
|
|
| 2705 |
- /* yv12_to_yuy2 */ |
|
| 2706 |
- if (srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P) {
|
|
| 2707 |
- if (dstFormat == PIX_FMT_YUYV422) |
|
| 2708 |
- c->swScale= planarToYuy2Wrapper; |
|
| 2709 |
- else if (dstFormat == PIX_FMT_UYVY422) |
|
| 2710 |
- c->swScale= planarToUyvyWrapper; |
|
| 2711 |
- } |
|
| 2712 |
- } |
|
| 2713 |
- if(srcFormat == PIX_FMT_YUYV422 && (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P)) |
|
| 2714 |
- c->swScale= yuyvToYuv420Wrapper; |
|
| 2715 |
- if(srcFormat == PIX_FMT_UYVY422 && (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P)) |
|
| 2716 |
- c->swScale= uyvyToYuv420Wrapper; |
|
| 2717 |
- if(srcFormat == PIX_FMT_YUYV422 && dstFormat == PIX_FMT_YUV422P) |
|
| 2718 |
- c->swScale= yuyvToYuv422Wrapper; |
|
| 2719 |
- if(srcFormat == PIX_FMT_UYVY422 && dstFormat == PIX_FMT_YUV422P) |
|
| 2720 |
- c->swScale= uyvyToYuv422Wrapper; |
|
| 2721 |
- |
|
| 2722 |
- /* simple copy */ |
|
| 2723 |
- if ( srcFormat == dstFormat |
|
| 2724 |
- || (srcFormat == PIX_FMT_YUVA420P && dstFormat == PIX_FMT_YUV420P) |
|
| 2725 |
- || (srcFormat == PIX_FMT_YUV420P && dstFormat == PIX_FMT_YUVA420P) |
|
| 2726 |
- || (isPlanarYUV(srcFormat) && isGray(dstFormat)) |
|
| 2727 |
- || (isPlanarYUV(dstFormat) && isGray(srcFormat)) |
|
| 2728 |
- || (isGray(dstFormat) && isGray(srcFormat)) |
|
| 2729 |
- || (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat) |
|
| 2730 |
- && c->chrDstHSubSample == c->chrSrcHSubSample |
|
| 2731 |
- && c->chrDstVSubSample == c->chrSrcVSubSample |
|
| 2732 |
- && dstFormat != PIX_FMT_NV12 && dstFormat != PIX_FMT_NV21 |
|
| 2733 |
- && srcFormat != PIX_FMT_NV12 && srcFormat != PIX_FMT_NV21)) |
|
| 2734 |
- {
|
|
| 2735 |
- if (isPacked(c->srcFormat)) |
|
| 2736 |
- c->swScale= packedCopyWrapper; |
|
| 2737 |
- else /* Planar YUV or gray */ |
|
| 2738 |
- c->swScale= planarCopyWrapper; |
|
| 2739 |
- } |
|
| 2740 |
- |
|
| 2741 |
- if (ARCH_BFIN) |
|
| 2742 |
- ff_bfin_get_unscaled_swscale(c); |
|
| 2743 |
- if (HAVE_ALTIVEC) |
|
| 2744 |
- ff_swscale_get_unscaled_altivec(c); |
|
| 2745 |
-} |
|
| 2746 |
- |
|
| 2747 |
-static void reset_ptr(const uint8_t* src[], int format) |
|
| 2748 |
-{
|
|
| 2749 |
- if(!isALPHA(format)) |
|
| 2750 |
- src[3]=NULL; |
|
| 2751 |
- if(!isPlanarYUV(format)) {
|
|
| 2752 |
- src[3]=src[2]=NULL; |
|
| 2753 |
- |
|
| 2754 |
- if (!usePal(format)) |
|
| 2755 |
- src[1]= NULL; |
|
| 2756 |
- } |
|
| 2757 |
-} |
|
| 2758 |
- |
|
| 2759 |
-static int check_image_pointers(uint8_t *data[4], enum PixelFormat pix_fmt, |
|
| 2760 |
- const int linesizes[4]) |
|
| 2761 |
-{
|
|
| 2762 |
- const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; |
|
| 2763 |
- int i; |
|
| 2764 |
- |
|
| 2765 |
- for (i = 0; i < 4; i++) {
|
|
| 2766 |
- int plane = desc->comp[i].plane; |
|
| 2767 |
- if (!data[plane] || !linesizes[plane]) |
|
| 2768 |
- return 0; |
|
| 2769 |
- } |
|
| 2770 |
- |
|
| 2771 |
- return 1; |
|
| 2772 |
-} |
|
| 2773 |
- |
|
| 2774 |
-/** |
|
| 2775 |
- * swscale wrapper, so we don't need to export the SwsContext. |
|
| 2776 |
- * Assumes planar YUV to be in YUV order instead of YVU. |
|
| 2777 |
- */ |
|
| 2778 |
-int sws_scale(SwsContext *c, const uint8_t* const src[], const int srcStride[], int srcSliceY, |
|
| 2779 |
- int srcSliceH, uint8_t* const dst[], const int dstStride[]) |
|
| 2780 |
-{
|
|
| 2781 |
- int i; |
|
| 2782 |
- const uint8_t* src2[4]= {src[0], src[1], src[2], src[3]};
|
|
| 2783 |
- uint8_t* dst2[4]= {dst[0], dst[1], dst[2], dst[3]};
|
|
| 2784 |
- |
|
| 2785 |
- // do not mess up sliceDir if we have a "trailing" 0-size slice |
|
| 2786 |
- if (srcSliceH == 0) |
|
| 2787 |
- return 0; |
|
| 2788 |
- |
|
| 2789 |
- if (!check_image_pointers(src, c->srcFormat, srcStride)) {
|
|
| 2790 |
- av_log(c, AV_LOG_ERROR, "bad src image pointers\n"); |
|
| 2791 |
- return 0; |
|
| 2792 |
- } |
|
| 2793 |
- if (!check_image_pointers(dst, c->dstFormat, dstStride)) {
|
|
| 2794 |
- av_log(c, AV_LOG_ERROR, "bad dst image pointers\n"); |
|
| 2795 |
- return 0; |
|
| 2796 |
- } |
|
| 2797 |
- |
|
| 2798 |
- if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
|
|
| 2799 |
- av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n"); |
|
| 2800 |
- return 0; |
|
| 2801 |
- } |
|
| 2802 |
- if (c->sliceDir == 0) {
|
|
| 2803 |
- if (srcSliceY == 0) c->sliceDir = 1; else c->sliceDir = -1; |
|
| 2804 |
- } |
|
| 2805 |
- |
|
| 2806 |
- if (usePal(c->srcFormat)) {
|
|
| 2807 |
- for (i=0; i<256; i++) {
|
|
| 2808 |
- int p, r, g, b,y,u,v; |
|
| 2809 |
- if(c->srcFormat == PIX_FMT_PAL8) {
|
|
| 2810 |
- p=((const uint32_t*)(src[1]))[i]; |
|
| 2811 |
- r= (p>>16)&0xFF; |
|
| 2812 |
- g= (p>> 8)&0xFF; |
|
| 2813 |
- b= p &0xFF; |
|
| 2814 |
- } else if(c->srcFormat == PIX_FMT_RGB8) {
|
|
| 2815 |
- r= (i>>5 )*36; |
|
| 2816 |
- g= ((i>>2)&7)*36; |
|
| 2817 |
- b= (i&3 )*85; |
|
| 2818 |
- } else if(c->srcFormat == PIX_FMT_BGR8) {
|
|
| 2819 |
- b= (i>>6 )*85; |
|
| 2820 |
- g= ((i>>3)&7)*36; |
|
| 2821 |
- r= (i&7 )*36; |
|
| 2822 |
- } else if(c->srcFormat == PIX_FMT_RGB4_BYTE) {
|
|
| 2823 |
- r= (i>>3 )*255; |
|
| 2824 |
- g= ((i>>1)&3)*85; |
|
| 2825 |
- b= (i&1 )*255; |
|
| 2826 |
- } else if(c->srcFormat == PIX_FMT_GRAY8 || c->srcFormat == PIX_FMT_Y400A) {
|
|
| 2827 |
- r = g = b = i; |
|
| 2828 |
- } else {
|
|
| 2829 |
- assert(c->srcFormat == PIX_FMT_BGR4_BYTE); |
|
| 2830 |
- b= (i>>3 )*255; |
|
| 2831 |
- g= ((i>>1)&3)*85; |
|
| 2832 |
- r= (i&1 )*255; |
|
| 2833 |
- } |
|
| 2834 |
- y= av_clip_uint8((RY*r + GY*g + BY*b + ( 33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT); |
|
| 2835 |
- u= av_clip_uint8((RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT); |
|
| 2836 |
- v= av_clip_uint8((RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT); |
|
| 2837 |
- c->pal_yuv[i]= y + (u<<8) + (v<<16); |
|
| 2838 |
- |
|
| 2839 |
- switch(c->dstFormat) {
|
|
| 2840 |
- case PIX_FMT_BGR32: |
|
| 2841 |
-#if !HAVE_BIGENDIAN |
|
| 2842 |
- case PIX_FMT_RGB24: |
|
| 2843 |
-#endif |
|
| 2844 |
- c->pal_rgb[i]= r + (g<<8) + (b<<16); |
|
| 2845 |
- break; |
|
| 2846 |
- case PIX_FMT_BGR32_1: |
|
| 2847 |
-#if HAVE_BIGENDIAN |
|
| 2848 |
- case PIX_FMT_BGR24: |
|
| 2849 |
-#endif |
|
| 2850 |
- c->pal_rgb[i]= (r + (g<<8) + (b<<16)) << 8; |
|
| 2851 |
- break; |
|
| 2852 |
- case PIX_FMT_RGB32_1: |
|
| 2853 |
-#if HAVE_BIGENDIAN |
|
| 2854 |
- case PIX_FMT_RGB24: |
|
| 2855 |
-#endif |
|
| 2856 |
- c->pal_rgb[i]= (b + (g<<8) + (r<<16)) << 8; |
|
| 2857 |
- break; |
|
| 2858 |
- case PIX_FMT_RGB32: |
|
| 2859 |
-#if !HAVE_BIGENDIAN |
|
| 2860 |
- case PIX_FMT_BGR24: |
|
| 2861 |
-#endif |
|
| 2862 |
- default: |
|
| 2863 |
- c->pal_rgb[i]= b + (g<<8) + (r<<16); |
|
| 2864 |
- } |
|
| 2865 |
- } |
|
| 2866 |
- } |
|
| 2867 |
- |
|
| 2868 |
- // copy strides, so they can safely be modified |
|
| 2869 |
- if (c->sliceDir == 1) {
|
|
| 2870 |
- // slices go from top to bottom |
|
| 2871 |
- int srcStride2[4]= {srcStride[0], srcStride[1], srcStride[2], srcStride[3]};
|
|
| 2872 |
- int dstStride2[4]= {dstStride[0], dstStride[1], dstStride[2], dstStride[3]};
|
|
| 2873 |
- |
|
| 2874 |
- reset_ptr(src2, c->srcFormat); |
|
| 2875 |
- reset_ptr((const uint8_t**)dst2, c->dstFormat); |
|
| 2876 |
- |
|
| 2877 |
- /* reset slice direction at end of frame */ |
|
| 2878 |
- if (srcSliceY + srcSliceH == c->srcH) |
|
| 2879 |
- c->sliceDir = 0; |
|
| 2880 |
- |
|
| 2881 |
- return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2, dstStride2); |
|
| 2882 |
- } else {
|
|
| 2883 |
- // slices go from bottom to top => we flip the image internally |
|
| 2884 |
- int srcStride2[4]= {-srcStride[0], -srcStride[1], -srcStride[2], -srcStride[3]};
|
|
| 2885 |
- int dstStride2[4]= {-dstStride[0], -dstStride[1], -dstStride[2], -dstStride[3]};
|
|
| 2886 |
- |
|
| 2887 |
- src2[0] += (srcSliceH-1)*srcStride[0]; |
|
| 2888 |
- if (!usePal(c->srcFormat)) |
|
| 2889 |
- src2[1] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[1]; |
|
| 2890 |
- src2[2] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[2]; |
|
| 2891 |
- src2[3] += (srcSliceH-1)*srcStride[3]; |
|
| 2892 |
- dst2[0] += ( c->dstH -1)*dstStride[0]; |
|
| 2893 |
- dst2[1] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[1]; |
|
| 2894 |
- dst2[2] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[2]; |
|
| 2895 |
- dst2[3] += ( c->dstH -1)*dstStride[3]; |
|
| 2896 |
- |
|
| 2897 |
- reset_ptr(src2, c->srcFormat); |
|
| 2898 |
- reset_ptr((const uint8_t**)dst2, c->dstFormat); |
|
| 2899 |
- |
|
| 2900 |
- /* reset slice direction at end of frame */ |
|
| 2901 |
- if (!srcSliceY) |
|
| 2902 |
- c->sliceDir = 0; |
|
| 2903 |
- |
|
| 2904 |
- return c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH, srcSliceH, dst2, dstStride2); |
|
| 2905 |
- } |
|
| 2906 |
-} |
|
| 2907 |
- |
|
| 2908 |
-/* Convert the palette to the same packed 32-bit format as the palette */ |
|
| 2909 |
-void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) |
|
| 2910 |
-{
|
|
| 2911 |
- int i; |
|
| 2912 |
- |
|
| 2913 |
- for (i=0; i<num_pixels; i++) |
|
| 2914 |
- ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]]; |
|
| 2915 |
-} |
|
| 2916 |
- |
|
| 2917 |
-/* Palette format: ABCD -> dst format: ABC */ |
|
| 2918 |
-void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) |
|
| 2919 |
-{
|
|
| 2920 |
- int i; |
|
| 2921 |
- |
|
| 2922 |
- for (i=0; i<num_pixels; i++) {
|
|
| 2923 |
- //FIXME slow? |
|
| 2924 |
- dst[0]= palette[src[i]*4+0]; |
|
| 2925 |
- dst[1]= palette[src[i]*4+1]; |
|
| 2926 |
- dst[2]= palette[src[i]*4+2]; |
|
| 2927 |
- dst+= 3; |
|
| 2928 |
- } |
|
| 2929 |
-} |
| ... | ... |
@@ -464,6 +464,13 @@ const char *sws_format_name(enum PixelFormat format); |
| 464 | 464 |
|| (x)==PIX_FMT_Y400A \ |
| 465 | 465 |
|| (x)==PIX_FMT_YUVA420P \ |
| 466 | 466 |
) |
| 467 |
+#define isPacked(x) ( \ |
|
| 468 |
+ (x)==PIX_FMT_PAL8 \ |
|
| 469 |
+ || (x)==PIX_FMT_YUYV422 \ |
|
| 470 |
+ || (x)==PIX_FMT_UYVY422 \ |
|
| 471 |
+ || (x)==PIX_FMT_Y400A \ |
|
| 472 |
+ || isAnyRGB(x) \ |
|
| 473 |
+ ) |
|
| 467 | 474 |
#define usePal(x) ((av_pix_fmt_descriptors[x].flags & PIX_FMT_PAL) || (x) == PIX_FMT_Y400A) |
| 468 | 475 |
|
| 469 | 476 |
extern const uint64_t ff_dither4[2]; |
| 470 | 477 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,887 @@ |
| 0 |
+/* |
|
| 1 |
+ * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at> |
|
| 2 |
+ * |
|
| 3 |
+ * This file is part of Libav. |
|
| 4 |
+ * |
|
| 5 |
+ * Libav is free software; you can redistribute it and/or |
|
| 6 |
+ * modify it under the terms of the GNU Lesser General Public |
|
| 7 |
+ * License as published by the Free Software Foundation; either |
|
| 8 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
| 9 |
+ * |
|
| 10 |
+ * Libav is distributed in the hope that it will be useful, |
|
| 11 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 12 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
| 13 |
+ * Lesser General Public License for more details. |
|
| 14 |
+ * |
|
| 15 |
+ * You should have received a copy of the GNU Lesser General Public |
|
| 16 |
+ * License along with Libav; if not, write to the Free Software |
|
| 17 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
| 18 |
+ */ |
|
| 19 |
+ |
|
| 20 |
+#include <inttypes.h> |
|
| 21 |
+#include <string.h> |
|
| 22 |
+#include <math.h> |
|
| 23 |
+#include <stdio.h> |
|
| 24 |
+#include "config.h" |
|
| 25 |
+#include <assert.h> |
|
| 26 |
+#include "swscale.h" |
|
| 27 |
+#include "swscale_internal.h" |
|
| 28 |
+#include "rgb2rgb.h" |
|
| 29 |
+#include "libavutil/intreadwrite.h" |
|
| 30 |
+#include "libavutil/cpu.h" |
|
| 31 |
+#include "libavutil/avutil.h" |
|
| 32 |
+#include "libavutil/mathematics.h" |
|
| 33 |
+#include "libavutil/bswap.h" |
|
| 34 |
+#include "libavutil/pixdesc.h" |
|
| 35 |
+ |
|
| 36 |
+#define RGB2YUV_SHIFT 15 |
|
| 37 |
+#define BY ( (int)(0.114*219/255*(1<<RGB2YUV_SHIFT)+0.5)) |
|
| 38 |
+#define BV (-(int)(0.081*224/255*(1<<RGB2YUV_SHIFT)+0.5)) |
|
| 39 |
+#define BU ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5)) |
|
| 40 |
+#define GY ( (int)(0.587*219/255*(1<<RGB2YUV_SHIFT)+0.5)) |
|
| 41 |
+#define GV (-(int)(0.419*224/255*(1<<RGB2YUV_SHIFT)+0.5)) |
|
| 42 |
+#define GU (-(int)(0.331*224/255*(1<<RGB2YUV_SHIFT)+0.5)) |
|
| 43 |
+#define RY ( (int)(0.299*219/255*(1<<RGB2YUV_SHIFT)+0.5)) |
|
| 44 |
+#define RV ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5)) |
|
| 45 |
+#define RU (-(int)(0.169*224/255*(1<<RGB2YUV_SHIFT)+0.5)) |
|
| 46 |
+ |
|
| 47 |
+static void fillPlane(uint8_t* plane, int stride, int width, int height, int y, uint8_t val) |
|
| 48 |
+{
|
|
| 49 |
+ int i; |
|
| 50 |
+ uint8_t *ptr = plane + stride*y; |
|
| 51 |
+ for (i=0; i<height; i++) {
|
|
| 52 |
+ memset(ptr, val, width); |
|
| 53 |
+ ptr += stride; |
|
| 54 |
+ } |
|
| 55 |
+} |
|
| 56 |
+ |
|
| 57 |
+static void copyPlane(const uint8_t *src, int srcStride, |
|
| 58 |
+ int srcSliceY, int srcSliceH, int width, |
|
| 59 |
+ uint8_t *dst, int dstStride) |
|
| 60 |
+{
|
|
| 61 |
+ dst += dstStride * srcSliceY; |
|
| 62 |
+ if (dstStride == srcStride && srcStride > 0) {
|
|
| 63 |
+ memcpy(dst, src, srcSliceH * dstStride); |
|
| 64 |
+ } else {
|
|
| 65 |
+ int i; |
|
| 66 |
+ for (i=0; i<srcSliceH; i++) {
|
|
| 67 |
+ memcpy(dst, src, width); |
|
| 68 |
+ src += srcStride; |
|
| 69 |
+ dst += dstStride; |
|
| 70 |
+ } |
|
| 71 |
+ } |
|
| 72 |
+} |
|
| 73 |
+ |
|
| 74 |
+static int planarToNv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 75 |
+ int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 76 |
+{
|
|
| 77 |
+ uint8_t *dst = dstParam[1] + dstStride[1]*srcSliceY/2; |
|
| 78 |
+ |
|
| 79 |
+ copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW, |
|
| 80 |
+ dstParam[0], dstStride[0]); |
|
| 81 |
+ |
|
| 82 |
+ if (c->dstFormat == PIX_FMT_NV12) |
|
| 83 |
+ interleaveBytes(src[1], src[2], dst, c->srcW/2, srcSliceH/2, srcStride[1], srcStride[2], dstStride[0]); |
|
| 84 |
+ else |
|
| 85 |
+ interleaveBytes(src[2], src[1], dst, c->srcW/2, srcSliceH/2, srcStride[2], srcStride[1], dstStride[0]); |
|
| 86 |
+ |
|
| 87 |
+ return srcSliceH; |
|
| 88 |
+} |
|
| 89 |
+ |
|
| 90 |
+static int planarToYuy2Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 91 |
+ int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 92 |
+{
|
|
| 93 |
+ uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 94 |
+ |
|
| 95 |
+ yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]); |
|
| 96 |
+ |
|
| 97 |
+ return srcSliceH; |
|
| 98 |
+} |
|
| 99 |
+ |
|
| 100 |
+static int planarToUyvyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 101 |
+ int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 102 |
+{
|
|
| 103 |
+ uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 104 |
+ |
|
| 105 |
+ yv12touyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]); |
|
| 106 |
+ |
|
| 107 |
+ return srcSliceH; |
|
| 108 |
+} |
|
| 109 |
+ |
|
| 110 |
+static int yuv422pToYuy2Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 111 |
+ int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 112 |
+{
|
|
| 113 |
+ uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 114 |
+ |
|
| 115 |
+ yuv422ptoyuy2(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]); |
|
| 116 |
+ |
|
| 117 |
+ return srcSliceH; |
|
| 118 |
+} |
|
| 119 |
+ |
|
| 120 |
+static int yuv422pToUyvyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 121 |
+ int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 122 |
+{
|
|
| 123 |
+ uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 124 |
+ |
|
| 125 |
+ yuv422ptouyvy(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]); |
|
| 126 |
+ |
|
| 127 |
+ return srcSliceH; |
|
| 128 |
+} |
|
| 129 |
+ |
|
| 130 |
+static int yuyvToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 131 |
+ int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 132 |
+{
|
|
| 133 |
+ uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 134 |
+ uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2; |
|
| 135 |
+ uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2; |
|
| 136 |
+ |
|
| 137 |
+ yuyvtoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); |
|
| 138 |
+ |
|
| 139 |
+ if (dstParam[3]) |
|
| 140 |
+ fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); |
|
| 141 |
+ |
|
| 142 |
+ return srcSliceH; |
|
| 143 |
+} |
|
| 144 |
+ |
|
| 145 |
+static int yuyvToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 146 |
+ int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 147 |
+{
|
|
| 148 |
+ uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 149 |
+ uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY; |
|
| 150 |
+ uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY; |
|
| 151 |
+ |
|
| 152 |
+ yuyvtoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); |
|
| 153 |
+ |
|
| 154 |
+ return srcSliceH; |
|
| 155 |
+} |
|
| 156 |
+ |
|
| 157 |
+static int uyvyToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 158 |
+ int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 159 |
+{
|
|
| 160 |
+ uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 161 |
+ uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2; |
|
| 162 |
+ uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2; |
|
| 163 |
+ |
|
| 164 |
+ uyvytoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); |
|
| 165 |
+ |
|
| 166 |
+ if (dstParam[3]) |
|
| 167 |
+ fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); |
|
| 168 |
+ |
|
| 169 |
+ return srcSliceH; |
|
| 170 |
+} |
|
| 171 |
+ |
|
| 172 |
+static int uyvyToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 173 |
+ int srcSliceH, uint8_t* dstParam[], int dstStride[]) |
|
| 174 |
+{
|
|
| 175 |
+ uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY; |
|
| 176 |
+ uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY; |
|
| 177 |
+ uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY; |
|
| 178 |
+ |
|
| 179 |
+ uyvytoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]); |
|
| 180 |
+ |
|
| 181 |
+ return srcSliceH; |
|
| 182 |
+} |
|
| 183 |
+ |
|
| 184 |
+static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) |
|
| 185 |
+{
|
|
| 186 |
+ int i; |
|
| 187 |
+ for (i=0; i<num_pixels; i++) |
|
| 188 |
+ ((uint32_t *) dst)[i] = ((const uint32_t *)palette)[src[i<<1]] | (src[(i<<1)+1] << 24); |
|
| 189 |
+} |
|
| 190 |
+ |
|
| 191 |
+static void gray8aToPacked32_1(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) |
|
| 192 |
+{
|
|
| 193 |
+ int i; |
|
| 194 |
+ |
|
| 195 |
+ for (i=0; i<num_pixels; i++) |
|
| 196 |
+ ((uint32_t *) dst)[i] = ((const uint32_t *)palette)[src[i<<1]] | src[(i<<1)+1]; |
|
| 197 |
+} |
|
| 198 |
+ |
|
| 199 |
+static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) |
|
| 200 |
+{
|
|
| 201 |
+ int i; |
|
| 202 |
+ |
|
| 203 |
+ for (i=0; i<num_pixels; i++) {
|
|
| 204 |
+ //FIXME slow? |
|
| 205 |
+ dst[0]= palette[src[i<<1]*4+0]; |
|
| 206 |
+ dst[1]= palette[src[i<<1]*4+1]; |
|
| 207 |
+ dst[2]= palette[src[i<<1]*4+2]; |
|
| 208 |
+ dst+= 3; |
|
| 209 |
+ } |
|
| 210 |
+} |
|
| 211 |
+ |
|
| 212 |
+static int palToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 213 |
+ int srcSliceH, uint8_t* dst[], int dstStride[]) |
|
| 214 |
+{
|
|
| 215 |
+ const enum PixelFormat srcFormat= c->srcFormat; |
|
| 216 |
+ const enum PixelFormat dstFormat= c->dstFormat; |
|
| 217 |
+ void (*conv)(const uint8_t *src, uint8_t *dst, int num_pixels, |
|
| 218 |
+ const uint8_t *palette)=NULL; |
|
| 219 |
+ int i; |
|
| 220 |
+ uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY; |
|
| 221 |
+ const uint8_t *srcPtr= src[0]; |
|
| 222 |
+ |
|
| 223 |
+ if (srcFormat == PIX_FMT_Y400A) {
|
|
| 224 |
+ switch (dstFormat) {
|
|
| 225 |
+ case PIX_FMT_RGB32 : conv = gray8aToPacked32; break; |
|
| 226 |
+ case PIX_FMT_BGR32 : conv = gray8aToPacked32; break; |
|
| 227 |
+ case PIX_FMT_BGR32_1: conv = gray8aToPacked32_1; break; |
|
| 228 |
+ case PIX_FMT_RGB32_1: conv = gray8aToPacked32_1; break; |
|
| 229 |
+ case PIX_FMT_RGB24 : conv = gray8aToPacked24; break; |
|
| 230 |
+ case PIX_FMT_BGR24 : conv = gray8aToPacked24; break; |
|
| 231 |
+ } |
|
| 232 |
+ } else if (usePal(srcFormat)) {
|
|
| 233 |
+ switch (dstFormat) {
|
|
| 234 |
+ case PIX_FMT_RGB32 : conv = sws_convertPalette8ToPacked32; break; |
|
| 235 |
+ case PIX_FMT_BGR32 : conv = sws_convertPalette8ToPacked32; break; |
|
| 236 |
+ case PIX_FMT_BGR32_1: conv = sws_convertPalette8ToPacked32; break; |
|
| 237 |
+ case PIX_FMT_RGB32_1: conv = sws_convertPalette8ToPacked32; break; |
|
| 238 |
+ case PIX_FMT_RGB24 : conv = sws_convertPalette8ToPacked24; break; |
|
| 239 |
+ case PIX_FMT_BGR24 : conv = sws_convertPalette8ToPacked24; break; |
|
| 240 |
+ } |
|
| 241 |
+ } |
|
| 242 |
+ |
|
| 243 |
+ if (!conv) |
|
| 244 |
+ av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n", |
|
| 245 |
+ sws_format_name(srcFormat), sws_format_name(dstFormat)); |
|
| 246 |
+ else {
|
|
| 247 |
+ for (i=0; i<srcSliceH; i++) {
|
|
| 248 |
+ conv(srcPtr, dstPtr, c->srcW, (uint8_t *) c->pal_rgb); |
|
| 249 |
+ srcPtr+= srcStride[0]; |
|
| 250 |
+ dstPtr+= dstStride[0]; |
|
| 251 |
+ } |
|
| 252 |
+ } |
|
| 253 |
+ |
|
| 254 |
+ return srcSliceH; |
|
| 255 |
+} |
|
| 256 |
+ |
|
| 257 |
+#define isRGBA32(x) ( \ |
|
| 258 |
+ (x) == PIX_FMT_ARGB \ |
|
| 259 |
+ || (x) == PIX_FMT_RGBA \ |
|
| 260 |
+ || (x) == PIX_FMT_BGRA \ |
|
| 261 |
+ || (x) == PIX_FMT_ABGR \ |
|
| 262 |
+ ) |
|
| 263 |
+ |
|
| 264 |
+/* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
|
|
| 265 |
+static int rgbToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 266 |
+ int srcSliceH, uint8_t* dst[], int dstStride[]) |
|
| 267 |
+{
|
|
| 268 |
+ const enum PixelFormat srcFormat= c->srcFormat; |
|
| 269 |
+ const enum PixelFormat dstFormat= c->dstFormat; |
|
| 270 |
+ const int srcBpp= (c->srcFormatBpp + 7) >> 3; |
|
| 271 |
+ const int dstBpp= (c->dstFormatBpp + 7) >> 3; |
|
| 272 |
+ const int srcId= c->srcFormatBpp >> 2; /* 1:0, 4:1, 8:2, 15:3, 16:4, 24:6, 32:8 */ |
|
| 273 |
+ const int dstId= c->dstFormatBpp >> 2; |
|
| 274 |
+ void (*conv)(const uint8_t *src, uint8_t *dst, int src_size)=NULL; |
|
| 275 |
+ |
|
| 276 |
+#define CONV_IS(src, dst) (srcFormat == PIX_FMT_##src && dstFormat == PIX_FMT_##dst) |
|
| 277 |
+ |
|
| 278 |
+ if (isRGBA32(srcFormat) && isRGBA32(dstFormat)) {
|
|
| 279 |
+ if ( CONV_IS(ABGR, RGBA) |
|
| 280 |
+ || CONV_IS(ARGB, BGRA) |
|
| 281 |
+ || CONV_IS(BGRA, ARGB) |
|
| 282 |
+ || CONV_IS(RGBA, ABGR)) conv = shuffle_bytes_3210; |
|
| 283 |
+ else if (CONV_IS(ABGR, ARGB) |
|
| 284 |
+ || CONV_IS(ARGB, ABGR)) conv = shuffle_bytes_0321; |
|
| 285 |
+ else if (CONV_IS(ABGR, BGRA) |
|
| 286 |
+ || CONV_IS(ARGB, RGBA)) conv = shuffle_bytes_1230; |
|
| 287 |
+ else if (CONV_IS(BGRA, RGBA) |
|
| 288 |
+ || CONV_IS(RGBA, BGRA)) conv = shuffle_bytes_2103; |
|
| 289 |
+ else if (CONV_IS(BGRA, ABGR) |
|
| 290 |
+ || CONV_IS(RGBA, ARGB)) conv = shuffle_bytes_3012; |
|
| 291 |
+ } else |
|
| 292 |
+ /* BGR -> BGR */ |
|
| 293 |
+ if ( (isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) |
|
| 294 |
+ || (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
|
|
| 295 |
+ switch(srcId | (dstId<<4)) {
|
|
| 296 |
+ case 0x34: conv= rgb16to15; break; |
|
| 297 |
+ case 0x36: conv= rgb24to15; break; |
|
| 298 |
+ case 0x38: conv= rgb32to15; break; |
|
| 299 |
+ case 0x43: conv= rgb15to16; break; |
|
| 300 |
+ case 0x46: conv= rgb24to16; break; |
|
| 301 |
+ case 0x48: conv= rgb32to16; break; |
|
| 302 |
+ case 0x63: conv= rgb15to24; break; |
|
| 303 |
+ case 0x64: conv= rgb16to24; break; |
|
| 304 |
+ case 0x68: conv= rgb32to24; break; |
|
| 305 |
+ case 0x83: conv= rgb15to32; break; |
|
| 306 |
+ case 0x84: conv= rgb16to32; break; |
|
| 307 |
+ case 0x86: conv= rgb24to32; break; |
|
| 308 |
+ } |
|
| 309 |
+ } else if ( (isBGRinInt(srcFormat) && isRGBinInt(dstFormat)) |
|
| 310 |
+ || (isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) {
|
|
| 311 |
+ switch(srcId | (dstId<<4)) {
|
|
| 312 |
+ case 0x33: conv= rgb15tobgr15; break; |
|
| 313 |
+ case 0x34: conv= rgb16tobgr15; break; |
|
| 314 |
+ case 0x36: conv= rgb24tobgr15; break; |
|
| 315 |
+ case 0x38: conv= rgb32tobgr15; break; |
|
| 316 |
+ case 0x43: conv= rgb15tobgr16; break; |
|
| 317 |
+ case 0x44: conv= rgb16tobgr16; break; |
|
| 318 |
+ case 0x46: conv= rgb24tobgr16; break; |
|
| 319 |
+ case 0x48: conv= rgb32tobgr16; break; |
|
| 320 |
+ case 0x63: conv= rgb15tobgr24; break; |
|
| 321 |
+ case 0x64: conv= rgb16tobgr24; break; |
|
| 322 |
+ case 0x66: conv= rgb24tobgr24; break; |
|
| 323 |
+ case 0x68: conv= rgb32tobgr24; break; |
|
| 324 |
+ case 0x83: conv= rgb15tobgr32; break; |
|
| 325 |
+ case 0x84: conv= rgb16tobgr32; break; |
|
| 326 |
+ case 0x86: conv= rgb24tobgr32; break; |
|
| 327 |
+ } |
|
| 328 |
+ } |
|
| 329 |
+ |
|
| 330 |
+ if (!conv) {
|
|
| 331 |
+ av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n", |
|
| 332 |
+ sws_format_name(srcFormat), sws_format_name(dstFormat)); |
|
| 333 |
+ } else {
|
|
| 334 |
+ const uint8_t *srcPtr= src[0]; |
|
| 335 |
+ uint8_t *dstPtr= dst[0]; |
|
| 336 |
+ if ((srcFormat == PIX_FMT_RGB32_1 || srcFormat == PIX_FMT_BGR32_1) && !isRGBA32(dstFormat)) |
|
| 337 |
+ srcPtr += ALT32_CORR; |
|
| 338 |
+ |
|
| 339 |
+ if ((dstFormat == PIX_FMT_RGB32_1 || dstFormat == PIX_FMT_BGR32_1) && !isRGBA32(srcFormat)) |
|
| 340 |
+ dstPtr += ALT32_CORR; |
|
| 341 |
+ |
|
| 342 |
+ if (dstStride[0]*srcBpp == srcStride[0]*dstBpp && srcStride[0] > 0) |
|
| 343 |
+ conv(srcPtr, dstPtr + dstStride[0]*srcSliceY, srcSliceH*srcStride[0]); |
|
| 344 |
+ else {
|
|
| 345 |
+ int i; |
|
| 346 |
+ dstPtr += dstStride[0]*srcSliceY; |
|
| 347 |
+ |
|
| 348 |
+ for (i=0; i<srcSliceH; i++) {
|
|
| 349 |
+ conv(srcPtr, dstPtr, c->srcW*srcBpp); |
|
| 350 |
+ srcPtr+= srcStride[0]; |
|
| 351 |
+ dstPtr+= dstStride[0]; |
|
| 352 |
+ } |
|
| 353 |
+ } |
|
| 354 |
+ } |
|
| 355 |
+ return srcSliceH; |
|
| 356 |
+} |
|
| 357 |
+ |
|
| 358 |
+static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 359 |
+ int srcSliceH, uint8_t* dst[], int dstStride[]) |
|
| 360 |
+{
|
|
| 361 |
+ rgb24toyv12( |
|
| 362 |
+ src[0], |
|
| 363 |
+ dst[0]+ srcSliceY *dstStride[0], |
|
| 364 |
+ dst[1]+(srcSliceY>>1)*dstStride[1], |
|
| 365 |
+ dst[2]+(srcSliceY>>1)*dstStride[2], |
|
| 366 |
+ c->srcW, srcSliceH, |
|
| 367 |
+ dstStride[0], dstStride[1], srcStride[0]); |
|
| 368 |
+ if (dst[3]) |
|
| 369 |
+ fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); |
|
| 370 |
+ return srcSliceH; |
|
| 371 |
+} |
|
| 372 |
+ |
|
| 373 |
+static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 374 |
+ int srcSliceH, uint8_t* dst[], int dstStride[]) |
|
| 375 |
+{
|
|
| 376 |
+ copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW, |
|
| 377 |
+ dst[0], dstStride[0]); |
|
| 378 |
+ |
|
| 379 |
+ planar2x(src[1], dst[1] + dstStride[1]*(srcSliceY >> 1), c->chrSrcW, |
|
| 380 |
+ srcSliceH >> 2, srcStride[1], dstStride[1]); |
|
| 381 |
+ planar2x(src[2], dst[2] + dstStride[2]*(srcSliceY >> 1), c->chrSrcW, |
|
| 382 |
+ srcSliceH >> 2, srcStride[2], dstStride[2]); |
|
| 383 |
+ if (dst[3]) |
|
| 384 |
+ fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255); |
|
| 385 |
+ return srcSliceH; |
|
| 386 |
+} |
|
| 387 |
+ |
|
| 388 |
+/* unscaled copy like stuff (assumes nearly identical formats) */ |
|
| 389 |
+static int packedCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 390 |
+ int srcSliceH, uint8_t* dst[], int dstStride[]) |
|
| 391 |
+{
|
|
| 392 |
+ if (dstStride[0]==srcStride[0] && srcStride[0] > 0) |
|
| 393 |
+ memcpy(dst[0] + dstStride[0]*srcSliceY, src[0], srcSliceH*dstStride[0]); |
|
| 394 |
+ else {
|
|
| 395 |
+ int i; |
|
| 396 |
+ const uint8_t *srcPtr= src[0]; |
|
| 397 |
+ uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY; |
|
| 398 |
+ int length=0; |
|
| 399 |
+ |
|
| 400 |
+ /* universal length finder */ |
|
| 401 |
+ while(length+c->srcW <= FFABS(dstStride[0]) |
|
| 402 |
+ && length+c->srcW <= FFABS(srcStride[0])) length+= c->srcW; |
|
| 403 |
+ assert(length!=0); |
|
| 404 |
+ |
|
| 405 |
+ for (i=0; i<srcSliceH; i++) {
|
|
| 406 |
+ memcpy(dstPtr, srcPtr, length); |
|
| 407 |
+ srcPtr+= srcStride[0]; |
|
| 408 |
+ dstPtr+= dstStride[0]; |
|
| 409 |
+ } |
|
| 410 |
+ } |
|
| 411 |
+ return srcSliceH; |
|
| 412 |
+} |
|
| 413 |
+ |
|
| 414 |
+static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, |
|
| 415 |
+ int srcSliceH, uint8_t* dst[], int dstStride[]) |
|
| 416 |
+{
|
|
| 417 |
+ int plane, i, j; |
|
| 418 |
+ for (plane=0; plane<4; plane++) {
|
|
| 419 |
+ int length= (plane==0 || plane==3) ? c->srcW : -((-c->srcW )>>c->chrDstHSubSample); |
|
| 420 |
+ int y= (plane==0 || plane==3) ? srcSliceY: -((-srcSliceY)>>c->chrDstVSubSample); |
|
| 421 |
+ int height= (plane==0 || plane==3) ? srcSliceH: -((-srcSliceH)>>c->chrDstVSubSample); |
|
| 422 |
+ const uint8_t *srcPtr= src[plane]; |
|
| 423 |
+ uint8_t *dstPtr= dst[plane] + dstStride[plane]*y; |
|
| 424 |
+ |
|
| 425 |
+ if (!dst[plane]) continue; |
|
| 426 |
+ // ignore palette for GRAY8 |
|
| 427 |
+ if (plane == 1 && !dst[2]) continue; |
|
| 428 |
+ if (!src[plane] || (plane == 1 && !src[2])) {
|
|
| 429 |
+ if(is16BPS(c->dstFormat)) |
|
| 430 |
+ length*=2; |
|
| 431 |
+ fillPlane(dst[plane], dstStride[plane], length, height, y, (plane==3) ? 255 : 128); |
|
| 432 |
+ } else {
|
|
| 433 |
+ if(is9_OR_10BPS(c->srcFormat)) {
|
|
| 434 |
+ const int src_depth = av_pix_fmt_descriptors[c->srcFormat].comp[plane].depth_minus1+1; |
|
| 435 |
+ const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1+1; |
|
| 436 |
+ const uint16_t *srcPtr2 = (const uint16_t*)srcPtr; |
|
| 437 |
+ |
|
| 438 |
+ if (is16BPS(c->dstFormat)) {
|
|
| 439 |
+ uint16_t *dstPtr2 = (uint16_t*)dstPtr; |
|
| 440 |
+#define COPY9_OR_10TO16(rfunc, wfunc) \ |
|
| 441 |
+ for (i = 0; i < height; i++) { \
|
|
| 442 |
+ for (j = 0; j < length; j++) { \
|
|
| 443 |
+ int srcpx = rfunc(&srcPtr2[j]); \ |
|
| 444 |
+ wfunc(&dstPtr2[j], (srcpx<<(16-src_depth)) | (srcpx>>(2*src_depth-16))); \ |
|
| 445 |
+ } \ |
|
| 446 |
+ dstPtr2 += dstStride[plane]/2; \ |
|
| 447 |
+ srcPtr2 += srcStride[plane]/2; \ |
|
| 448 |
+ } |
|
| 449 |
+ if (isBE(c->dstFormat)) {
|
|
| 450 |
+ if (isBE(c->srcFormat)) {
|
|
| 451 |
+ COPY9_OR_10TO16(AV_RB16, AV_WB16); |
|
| 452 |
+ } else {
|
|
| 453 |
+ COPY9_OR_10TO16(AV_RL16, AV_WB16); |
|
| 454 |
+ } |
|
| 455 |
+ } else {
|
|
| 456 |
+ if (isBE(c->srcFormat)) {
|
|
| 457 |
+ COPY9_OR_10TO16(AV_RB16, AV_WL16); |
|
| 458 |
+ } else {
|
|
| 459 |
+ COPY9_OR_10TO16(AV_RL16, AV_WL16); |
|
| 460 |
+ } |
|
| 461 |
+ } |
|
| 462 |
+ } else if (is9_OR_10BPS(c->dstFormat)) {
|
|
| 463 |
+ uint16_t *dstPtr2 = (uint16_t*)dstPtr; |
|
| 464 |
+#define COPY9_OR_10TO9_OR_10(loop) \ |
|
| 465 |
+ for (i = 0; i < height; i++) { \
|
|
| 466 |
+ for (j = 0; j < length; j++) { \
|
|
| 467 |
+ loop; \ |
|
| 468 |
+ } \ |
|
| 469 |
+ dstPtr2 += dstStride[plane]/2; \ |
|
| 470 |
+ srcPtr2 += srcStride[plane]/2; \ |
|
| 471 |
+ } |
|
| 472 |
+#define COPY9_OR_10TO9_OR_10_2(rfunc, wfunc) \ |
|
| 473 |
+ if (dst_depth > src_depth) { \
|
|
| 474 |
+ COPY9_OR_10TO9_OR_10(int srcpx = rfunc(&srcPtr2[j]); \ |
|
| 475 |
+ wfunc(&dstPtr2[j], (srcpx << 1) | (srcpx >> 9))); \ |
|
| 476 |
+ } else if (dst_depth < src_depth) { \
|
|
| 477 |
+ COPY9_OR_10TO9_OR_10(wfunc(&dstPtr2[j], rfunc(&srcPtr2[j]) >> 1)); \ |
|
| 478 |
+ } else { \
|
|
| 479 |
+ COPY9_OR_10TO9_OR_10(wfunc(&dstPtr2[j], rfunc(&srcPtr2[j]))); \ |
|
| 480 |
+ } |
|
| 481 |
+ if (isBE(c->dstFormat)) {
|
|
| 482 |
+ if (isBE(c->srcFormat)) {
|
|
| 483 |
+ COPY9_OR_10TO9_OR_10_2(AV_RB16, AV_WB16); |
|
| 484 |
+ } else {
|
|
| 485 |
+ COPY9_OR_10TO9_OR_10_2(AV_RL16, AV_WB16); |
|
| 486 |
+ } |
|
| 487 |
+ } else {
|
|
| 488 |
+ if (isBE(c->srcFormat)) {
|
|
| 489 |
+ COPY9_OR_10TO9_OR_10_2(AV_RB16, AV_WL16); |
|
| 490 |
+ } else {
|
|
| 491 |
+ COPY9_OR_10TO9_OR_10_2(AV_RL16, AV_WL16); |
|
| 492 |
+ } |
|
| 493 |
+ } |
|
| 494 |
+ } else {
|
|
| 495 |
+ // FIXME Maybe dither instead. |
|
| 496 |
+#define COPY9_OR_10TO8(rfunc) \ |
|
| 497 |
+ for (i = 0; i < height; i++) { \
|
|
| 498 |
+ for (j = 0; j < length; j++) { \
|
|
| 499 |
+ dstPtr[j] = rfunc(&srcPtr2[j])>>(src_depth-8); \ |
|
| 500 |
+ } \ |
|
| 501 |
+ dstPtr += dstStride[plane]; \ |
|
| 502 |
+ srcPtr2 += srcStride[plane]/2; \ |
|
| 503 |
+ } |
|
| 504 |
+ if (isBE(c->srcFormat)) {
|
|
| 505 |
+ COPY9_OR_10TO8(AV_RB16); |
|
| 506 |
+ } else {
|
|
| 507 |
+ COPY9_OR_10TO8(AV_RL16); |
|
| 508 |
+ } |
|
| 509 |
+ } |
|
| 510 |
+ } else if(is9_OR_10BPS(c->dstFormat)) {
|
|
| 511 |
+ const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1+1; |
|
| 512 |
+ uint16_t *dstPtr2 = (uint16_t*)dstPtr; |
|
| 513 |
+ |
|
| 514 |
+ if (is16BPS(c->srcFormat)) {
|
|
| 515 |
+ const uint16_t *srcPtr2 = (const uint16_t*)srcPtr; |
|
| 516 |
+#define COPY16TO9_OR_10(rfunc, wfunc) \ |
|
| 517 |
+ for (i = 0; i < height; i++) { \
|
|
| 518 |
+ for (j = 0; j < length; j++) { \
|
|
| 519 |
+ wfunc(&dstPtr2[j], rfunc(&srcPtr2[j])>>(16-dst_depth)); \ |
|
| 520 |
+ } \ |
|
| 521 |
+ dstPtr2 += dstStride[plane]/2; \ |
|
| 522 |
+ srcPtr2 += srcStride[plane]/2; \ |
|
| 523 |
+ } |
|
| 524 |
+ if (isBE(c->dstFormat)) {
|
|
| 525 |
+ if (isBE(c->srcFormat)) {
|
|
| 526 |
+ COPY16TO9_OR_10(AV_RB16, AV_WB16); |
|
| 527 |
+ } else {
|
|
| 528 |
+ COPY16TO9_OR_10(AV_RL16, AV_WB16); |
|
| 529 |
+ } |
|
| 530 |
+ } else {
|
|
| 531 |
+ if (isBE(c->srcFormat)) {
|
|
| 532 |
+ COPY16TO9_OR_10(AV_RB16, AV_WL16); |
|
| 533 |
+ } else {
|
|
| 534 |
+ COPY16TO9_OR_10(AV_RL16, AV_WL16); |
|
| 535 |
+ } |
|
| 536 |
+ } |
|
| 537 |
+ } else /* 8bit */ {
|
|
| 538 |
+#define COPY8TO9_OR_10(wfunc) \ |
|
| 539 |
+ for (i = 0; i < height; i++) { \
|
|
| 540 |
+ for (j = 0; j < length; j++) { \
|
|
| 541 |
+ const int srcpx = srcPtr[j]; \ |
|
| 542 |
+ wfunc(&dstPtr2[j], (srcpx<<(dst_depth-8)) | (srcpx >> (16-dst_depth))); \ |
|
| 543 |
+ } \ |
|
| 544 |
+ dstPtr2 += dstStride[plane]/2; \ |
|
| 545 |
+ srcPtr += srcStride[plane]; \ |
|
| 546 |
+ } |
|
| 547 |
+ if (isBE(c->dstFormat)) {
|
|
| 548 |
+ COPY8TO9_OR_10(AV_WB16); |
|
| 549 |
+ } else {
|
|
| 550 |
+ COPY8TO9_OR_10(AV_WL16); |
|
| 551 |
+ } |
|
| 552 |
+ } |
|
| 553 |
+ } else if(is16BPS(c->srcFormat) && !is16BPS(c->dstFormat)) {
|
|
| 554 |
+ if (!isBE(c->srcFormat)) srcPtr++; |
|
| 555 |
+ for (i=0; i<height; i++) {
|
|
| 556 |
+ for (j=0; j<length; j++) dstPtr[j] = srcPtr[j<<1]; |
|
| 557 |
+ srcPtr+= srcStride[plane]; |
|
| 558 |
+ dstPtr+= dstStride[plane]; |
|
| 559 |
+ } |
|
| 560 |
+ } else if(!is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) {
|
|
| 561 |
+ for (i=0; i<height; i++) {
|
|
| 562 |
+ for (j=0; j<length; j++) {
|
|
| 563 |
+ dstPtr[ j<<1 ] = srcPtr[j]; |
|
| 564 |
+ dstPtr[(j<<1)+1] = srcPtr[j]; |
|
| 565 |
+ } |
|
| 566 |
+ srcPtr+= srcStride[plane]; |
|
| 567 |
+ dstPtr+= dstStride[plane]; |
|
| 568 |
+ } |
|
| 569 |
+ } else if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat) |
|
| 570 |
+ && isBE(c->srcFormat) != isBE(c->dstFormat)) {
|
|
| 571 |
+ |
|
| 572 |
+ for (i=0; i<height; i++) {
|
|
| 573 |
+ for (j=0; j<length; j++) |
|
| 574 |
+ ((uint16_t*)dstPtr)[j] = av_bswap16(((const uint16_t*)srcPtr)[j]); |
|
| 575 |
+ srcPtr+= srcStride[plane]; |
|
| 576 |
+ dstPtr+= dstStride[plane]; |
|
| 577 |
+ } |
|
| 578 |
+ } else if (dstStride[plane] == srcStride[plane] && |
|
| 579 |
+ srcStride[plane] > 0 && srcStride[plane] == length) {
|
|
| 580 |
+ memcpy(dst[plane] + dstStride[plane]*y, src[plane], |
|
| 581 |
+ height*dstStride[plane]); |
|
| 582 |
+ } else {
|
|
| 583 |
+ if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) |
|
| 584 |
+ length*=2; |
|
| 585 |
+ for (i=0; i<height; i++) {
|
|
| 586 |
+ memcpy(dstPtr, srcPtr, length); |
|
| 587 |
+ srcPtr+= srcStride[plane]; |
|
| 588 |
+ dstPtr+= dstStride[plane]; |
|
| 589 |
+ } |
|
| 590 |
+ } |
|
| 591 |
+ } |
|
| 592 |
+ } |
|
| 593 |
+ return srcSliceH; |
|
| 594 |
+} |
|
| 595 |
+ |
|
| 596 |
+void ff_get_unscaled_swscale(SwsContext *c) |
|
| 597 |
+{
|
|
| 598 |
+ const enum PixelFormat srcFormat = c->srcFormat; |
|
| 599 |
+ const enum PixelFormat dstFormat = c->dstFormat; |
|
| 600 |
+ const int flags = c->flags; |
|
| 601 |
+ const int dstH = c->dstH; |
|
| 602 |
+ int needsDither; |
|
| 603 |
+ |
|
| 604 |
+ needsDither= isAnyRGB(dstFormat) |
|
| 605 |
+ && c->dstFormatBpp < 24 |
|
| 606 |
+ && (c->dstFormatBpp < c->srcFormatBpp || (!isAnyRGB(srcFormat))); |
|
| 607 |
+ |
|
| 608 |
+ /* yv12_to_nv12 */ |
|
| 609 |
+ if ((srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P) && (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21)) {
|
|
| 610 |
+ c->swScale= planarToNv12Wrapper; |
|
| 611 |
+ } |
|
| 612 |
+ /* yuv2bgr */ |
|
| 613 |
+ if ((srcFormat==PIX_FMT_YUV420P || srcFormat==PIX_FMT_YUV422P || srcFormat==PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) |
|
| 614 |
+ && !(flags & SWS_ACCURATE_RND) && !(dstH&1)) {
|
|
| 615 |
+ c->swScale= ff_yuv2rgb_get_func_ptr(c); |
|
| 616 |
+ } |
|
| 617 |
+ |
|
| 618 |
+ if (srcFormat==PIX_FMT_YUV410P && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_BITEXACT)) {
|
|
| 619 |
+ c->swScale= yvu9ToYv12Wrapper; |
|
| 620 |
+ } |
|
| 621 |
+ |
|
| 622 |
+ /* bgr24toYV12 */ |
|
| 623 |
+ if (srcFormat==PIX_FMT_BGR24 && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_ACCURATE_RND)) |
|
| 624 |
+ c->swScale= bgr24ToYv12Wrapper; |
|
| 625 |
+ |
|
| 626 |
+ /* RGB/BGR -> RGB/BGR (no dither needed forms) */ |
|
| 627 |
+ if ( isAnyRGB(srcFormat) |
|
| 628 |
+ && isAnyRGB(dstFormat) |
|
| 629 |
+ && srcFormat != PIX_FMT_BGR8 && dstFormat != PIX_FMT_BGR8 |
|
| 630 |
+ && srcFormat != PIX_FMT_RGB8 && dstFormat != PIX_FMT_RGB8 |
|
| 631 |
+ && srcFormat != PIX_FMT_BGR4 && dstFormat != PIX_FMT_BGR4 |
|
| 632 |
+ && srcFormat != PIX_FMT_RGB4 && dstFormat != PIX_FMT_RGB4 |
|
| 633 |
+ && srcFormat != PIX_FMT_BGR4_BYTE && dstFormat != PIX_FMT_BGR4_BYTE |
|
| 634 |
+ && srcFormat != PIX_FMT_RGB4_BYTE && dstFormat != PIX_FMT_RGB4_BYTE |
|
| 635 |
+ && srcFormat != PIX_FMT_MONOBLACK && dstFormat != PIX_FMT_MONOBLACK |
|
| 636 |
+ && srcFormat != PIX_FMT_MONOWHITE && dstFormat != PIX_FMT_MONOWHITE |
|
| 637 |
+ && srcFormat != PIX_FMT_RGB48LE && dstFormat != PIX_FMT_RGB48LE |
|
| 638 |
+ && srcFormat != PIX_FMT_RGB48BE && dstFormat != PIX_FMT_RGB48BE |
|
| 639 |
+ && srcFormat != PIX_FMT_BGR48LE && dstFormat != PIX_FMT_BGR48LE |
|
| 640 |
+ && srcFormat != PIX_FMT_BGR48BE && dstFormat != PIX_FMT_BGR48BE |
|
| 641 |
+ && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)))) |
|
| 642 |
+ c->swScale= rgbToRgbWrapper; |
|
| 643 |
+ |
|
| 644 |
+ if ((usePal(srcFormat) && ( |
|
| 645 |
+ dstFormat == PIX_FMT_RGB32 || |
|
| 646 |
+ dstFormat == PIX_FMT_RGB32_1 || |
|
| 647 |
+ dstFormat == PIX_FMT_RGB24 || |
|
| 648 |
+ dstFormat == PIX_FMT_BGR32 || |
|
| 649 |
+ dstFormat == PIX_FMT_BGR32_1 || |
|
| 650 |
+ dstFormat == PIX_FMT_BGR24))) |
|
| 651 |
+ c->swScale= palToRgbWrapper; |
|
| 652 |
+ |
|
| 653 |
+ if (srcFormat == PIX_FMT_YUV422P) {
|
|
| 654 |
+ if (dstFormat == PIX_FMT_YUYV422) |
|
| 655 |
+ c->swScale= yuv422pToYuy2Wrapper; |
|
| 656 |
+ else if (dstFormat == PIX_FMT_UYVY422) |
|
| 657 |
+ c->swScale= yuv422pToUyvyWrapper; |
|
| 658 |
+ } |
|
| 659 |
+ |
|
| 660 |
+ /* LQ converters if -sws 0 or -sws 4*/ |
|
| 661 |
+ if (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)) {
|
|
| 662 |
+ /* yv12_to_yuy2 */ |
|
| 663 |
+ if (srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P) {
|
|
| 664 |
+ if (dstFormat == PIX_FMT_YUYV422) |
|
| 665 |
+ c->swScale= planarToYuy2Wrapper; |
|
| 666 |
+ else if (dstFormat == PIX_FMT_UYVY422) |
|
| 667 |
+ c->swScale= planarToUyvyWrapper; |
|
| 668 |
+ } |
|
| 669 |
+ } |
|
| 670 |
+ if(srcFormat == PIX_FMT_YUYV422 && (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P)) |
|
| 671 |
+ c->swScale= yuyvToYuv420Wrapper; |
|
| 672 |
+ if(srcFormat == PIX_FMT_UYVY422 && (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P)) |
|
| 673 |
+ c->swScale= uyvyToYuv420Wrapper; |
|
| 674 |
+ if(srcFormat == PIX_FMT_YUYV422 && dstFormat == PIX_FMT_YUV422P) |
|
| 675 |
+ c->swScale= yuyvToYuv422Wrapper; |
|
| 676 |
+ if(srcFormat == PIX_FMT_UYVY422 && dstFormat == PIX_FMT_YUV422P) |
|
| 677 |
+ c->swScale= uyvyToYuv422Wrapper; |
|
| 678 |
+ |
|
| 679 |
+ /* simple copy */ |
|
| 680 |
+ if ( srcFormat == dstFormat |
|
| 681 |
+ || (srcFormat == PIX_FMT_YUVA420P && dstFormat == PIX_FMT_YUV420P) |
|
| 682 |
+ || (srcFormat == PIX_FMT_YUV420P && dstFormat == PIX_FMT_YUVA420P) |
|
| 683 |
+ || (isPlanarYUV(srcFormat) && isGray(dstFormat)) |
|
| 684 |
+ || (isPlanarYUV(dstFormat) && isGray(srcFormat)) |
|
| 685 |
+ || (isGray(dstFormat) && isGray(srcFormat)) |
|
| 686 |
+ || (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat) |
|
| 687 |
+ && c->chrDstHSubSample == c->chrSrcHSubSample |
|
| 688 |
+ && c->chrDstVSubSample == c->chrSrcVSubSample |
|
| 689 |
+ && dstFormat != PIX_FMT_NV12 && dstFormat != PIX_FMT_NV21 |
|
| 690 |
+ && srcFormat != PIX_FMT_NV12 && srcFormat != PIX_FMT_NV21)) |
|
| 691 |
+ {
|
|
| 692 |
+ if (isPacked(c->srcFormat)) |
|
| 693 |
+ c->swScale= packedCopyWrapper; |
|
| 694 |
+ else /* Planar YUV or gray */ |
|
| 695 |
+ c->swScale= planarCopyWrapper; |
|
| 696 |
+ } |
|
| 697 |
+ |
|
| 698 |
+ if (ARCH_BFIN) |
|
| 699 |
+ ff_bfin_get_unscaled_swscale(c); |
|
| 700 |
+ if (HAVE_ALTIVEC) |
|
| 701 |
+ ff_swscale_get_unscaled_altivec(c); |
|
| 702 |
+} |
|
| 703 |
+ |
|
| 704 |
+static void reset_ptr(const uint8_t* src[], int format) |
|
| 705 |
+{
|
|
| 706 |
+ if(!isALPHA(format)) |
|
| 707 |
+ src[3]=NULL; |
|
| 708 |
+ if(!isPlanarYUV(format)) {
|
|
| 709 |
+ src[3]=src[2]=NULL; |
|
| 710 |
+ |
|
| 711 |
+ if (!usePal(format)) |
|
| 712 |
+ src[1]= NULL; |
|
| 713 |
+ } |
|
| 714 |
+} |
|
| 715 |
+ |
|
| 716 |
+static int check_image_pointers(uint8_t *data[4], enum PixelFormat pix_fmt, |
|
| 717 |
+ const int linesizes[4]) |
|
| 718 |
+{
|
|
| 719 |
+ const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; |
|
| 720 |
+ int i; |
|
| 721 |
+ |
|
| 722 |
+ for (i = 0; i < 4; i++) {
|
|
| 723 |
+ int plane = desc->comp[i].plane; |
|
| 724 |
+ if (!data[plane] || !linesizes[plane]) |
|
| 725 |
+ return 0; |
|
| 726 |
+ } |
|
| 727 |
+ |
|
| 728 |
+ return 1; |
|
| 729 |
+} |
|
| 730 |
+ |
|
| 731 |
+/** |
|
| 732 |
+ * swscale wrapper, so we don't need to export the SwsContext. |
|
| 733 |
+ * Assumes planar YUV to be in YUV order instead of YVU. |
|
| 734 |
+ */ |
|
| 735 |
+int sws_scale(SwsContext *c, const uint8_t* const src[], const int srcStride[], int srcSliceY, |
|
| 736 |
+ int srcSliceH, uint8_t* const dst[], const int dstStride[]) |
|
| 737 |
+{
|
|
| 738 |
+ int i; |
|
| 739 |
+ const uint8_t* src2[4]= {src[0], src[1], src[2], src[3]};
|
|
| 740 |
+ uint8_t* dst2[4]= {dst[0], dst[1], dst[2], dst[3]};
|
|
| 741 |
+ |
|
| 742 |
+ // do not mess up sliceDir if we have a "trailing" 0-size slice |
|
| 743 |
+ if (srcSliceH == 0) |
|
| 744 |
+ return 0; |
|
| 745 |
+ |
|
| 746 |
+ if (!check_image_pointers(src, c->srcFormat, srcStride)) {
|
|
| 747 |
+ av_log(c, AV_LOG_ERROR, "bad src image pointers\n"); |
|
| 748 |
+ return 0; |
|
| 749 |
+ } |
|
| 750 |
+ if (!check_image_pointers(dst, c->dstFormat, dstStride)) {
|
|
| 751 |
+ av_log(c, AV_LOG_ERROR, "bad dst image pointers\n"); |
|
| 752 |
+ return 0; |
|
| 753 |
+ } |
|
| 754 |
+ |
|
| 755 |
+ if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
|
|
| 756 |
+ av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n"); |
|
| 757 |
+ return 0; |
|
| 758 |
+ } |
|
| 759 |
+ if (c->sliceDir == 0) {
|
|
| 760 |
+ if (srcSliceY == 0) c->sliceDir = 1; else c->sliceDir = -1; |
|
| 761 |
+ } |
|
| 762 |
+ |
|
| 763 |
+ if (usePal(c->srcFormat)) {
|
|
| 764 |
+ for (i=0; i<256; i++) {
|
|
| 765 |
+ int p, r, g, b,y,u,v; |
|
| 766 |
+ if(c->srcFormat == PIX_FMT_PAL8) {
|
|
| 767 |
+ p=((const uint32_t*)(src[1]))[i]; |
|
| 768 |
+ r= (p>>16)&0xFF; |
|
| 769 |
+ g= (p>> 8)&0xFF; |
|
| 770 |
+ b= p &0xFF; |
|
| 771 |
+ } else if(c->srcFormat == PIX_FMT_RGB8) {
|
|
| 772 |
+ r= (i>>5 )*36; |
|
| 773 |
+ g= ((i>>2)&7)*36; |
|
| 774 |
+ b= (i&3 )*85; |
|
| 775 |
+ } else if(c->srcFormat == PIX_FMT_BGR8) {
|
|
| 776 |
+ b= (i>>6 )*85; |
|
| 777 |
+ g= ((i>>3)&7)*36; |
|
| 778 |
+ r= (i&7 )*36; |
|
| 779 |
+ } else if(c->srcFormat == PIX_FMT_RGB4_BYTE) {
|
|
| 780 |
+ r= (i>>3 )*255; |
|
| 781 |
+ g= ((i>>1)&3)*85; |
|
| 782 |
+ b= (i&1 )*255; |
|
| 783 |
+ } else if(c->srcFormat == PIX_FMT_GRAY8 || c->srcFormat == PIX_FMT_Y400A) {
|
|
| 784 |
+ r = g = b = i; |
|
| 785 |
+ } else {
|
|
| 786 |
+ assert(c->srcFormat == PIX_FMT_BGR4_BYTE); |
|
| 787 |
+ b= (i>>3 )*255; |
|
| 788 |
+ g= ((i>>1)&3)*85; |
|
| 789 |
+ r= (i&1 )*255; |
|
| 790 |
+ } |
|
| 791 |
+ y= av_clip_uint8((RY*r + GY*g + BY*b + ( 33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT); |
|
| 792 |
+ u= av_clip_uint8((RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT); |
|
| 793 |
+ v= av_clip_uint8((RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT); |
|
| 794 |
+ c->pal_yuv[i]= y + (u<<8) + (v<<16); |
|
| 795 |
+ |
|
| 796 |
+ switch(c->dstFormat) {
|
|
| 797 |
+ case PIX_FMT_BGR32: |
|
| 798 |
+#if !HAVE_BIGENDIAN |
|
| 799 |
+ case PIX_FMT_RGB24: |
|
| 800 |
+#endif |
|
| 801 |
+ c->pal_rgb[i]= r + (g<<8) + (b<<16); |
|
| 802 |
+ break; |
|
| 803 |
+ case PIX_FMT_BGR32_1: |
|
| 804 |
+#if HAVE_BIGENDIAN |
|
| 805 |
+ case PIX_FMT_BGR24: |
|
| 806 |
+#endif |
|
| 807 |
+ c->pal_rgb[i]= (r + (g<<8) + (b<<16)) << 8; |
|
| 808 |
+ break; |
|
| 809 |
+ case PIX_FMT_RGB32_1: |
|
| 810 |
+#if HAVE_BIGENDIAN |
|
| 811 |
+ case PIX_FMT_RGB24: |
|
| 812 |
+#endif |
|
| 813 |
+ c->pal_rgb[i]= (b + (g<<8) + (r<<16)) << 8; |
|
| 814 |
+ break; |
|
| 815 |
+ case PIX_FMT_RGB32: |
|
| 816 |
+#if !HAVE_BIGENDIAN |
|
| 817 |
+ case PIX_FMT_BGR24: |
|
| 818 |
+#endif |
|
| 819 |
+ default: |
|
| 820 |
+ c->pal_rgb[i]= b + (g<<8) + (r<<16); |
|
| 821 |
+ } |
|
| 822 |
+ } |
|
| 823 |
+ } |
|
| 824 |
+ |
|
| 825 |
+ // copy strides, so they can safely be modified |
|
| 826 |
+ if (c->sliceDir == 1) {
|
|
| 827 |
+ // slices go from top to bottom |
|
| 828 |
+ int srcStride2[4]= {srcStride[0], srcStride[1], srcStride[2], srcStride[3]};
|
|
| 829 |
+ int dstStride2[4]= {dstStride[0], dstStride[1], dstStride[2], dstStride[3]};
|
|
| 830 |
+ |
|
| 831 |
+ reset_ptr(src2, c->srcFormat); |
|
| 832 |
+ reset_ptr((const uint8_t**)dst2, c->dstFormat); |
|
| 833 |
+ |
|
| 834 |
+ /* reset slice direction at end of frame */ |
|
| 835 |
+ if (srcSliceY + srcSliceH == c->srcH) |
|
| 836 |
+ c->sliceDir = 0; |
|
| 837 |
+ |
|
| 838 |
+ return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2, dstStride2); |
|
| 839 |
+ } else {
|
|
| 840 |
+ // slices go from bottom to top => we flip the image internally |
|
| 841 |
+ int srcStride2[4]= {-srcStride[0], -srcStride[1], -srcStride[2], -srcStride[3]};
|
|
| 842 |
+ int dstStride2[4]= {-dstStride[0], -dstStride[1], -dstStride[2], -dstStride[3]};
|
|
| 843 |
+ |
|
| 844 |
+ src2[0] += (srcSliceH-1)*srcStride[0]; |
|
| 845 |
+ if (!usePal(c->srcFormat)) |
|
| 846 |
+ src2[1] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[1]; |
|
| 847 |
+ src2[2] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[2]; |
|
| 848 |
+ src2[3] += (srcSliceH-1)*srcStride[3]; |
|
| 849 |
+ dst2[0] += ( c->dstH -1)*dstStride[0]; |
|
| 850 |
+ dst2[1] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[1]; |
|
| 851 |
+ dst2[2] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[2]; |
|
| 852 |
+ dst2[3] += ( c->dstH -1)*dstStride[3]; |
|
| 853 |
+ |
|
| 854 |
+ reset_ptr(src2, c->srcFormat); |
|
| 855 |
+ reset_ptr((const uint8_t**)dst2, c->dstFormat); |
|
| 856 |
+ |
|
| 857 |
+ /* reset slice direction at end of frame */ |
|
| 858 |
+ if (!srcSliceY) |
|
| 859 |
+ c->sliceDir = 0; |
|
| 860 |
+ |
|
| 861 |
+ return c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH, srcSliceH, dst2, dstStride2); |
|
| 862 |
+ } |
|
| 863 |
+} |
|
| 864 |
+ |
|
| 865 |
+/* Convert the palette to the same packed 32-bit format as the palette */ |
|
| 866 |
+void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) |
|
| 867 |
+{
|
|
| 868 |
+ int i; |
|
| 869 |
+ |
|
| 870 |
+ for (i=0; i<num_pixels; i++) |
|
| 871 |
+ ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]]; |
|
| 872 |
+} |
|
| 873 |
+ |
|
| 874 |
+/* Palette format: ABCD -> dst format: ABC */ |
|
| 875 |
+void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette) |
|
| 876 |
+{
|
|
| 877 |
+ int i; |
|
| 878 |
+ |
|
| 879 |
+ for (i=0; i<num_pixels; i++) {
|
|
| 880 |
+ //FIXME slow? |
|
| 881 |
+ dst[0]= palette[src[i]*4+0]; |
|
| 882 |
+ dst[1]= palette[src[i]*4+1]; |
|
| 883 |
+ dst[2]= palette[src[i]*4+2]; |
|
| 884 |
+ dst+= 3; |
|
| 885 |
+ } |
|
| 886 |
+} |