}
}
+static int packed_16bpc_bswap(SwsContext *c, const uint8_t* src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t* dst[], int dstStride[])
+{
+ int i, j;
+ int srcstr = srcStride[0] >> 1;
+ int dststr = dstStride[0] >> 1;
+ uint16_t *dstPtr = (uint16_t *)dst[0];
+ const uint16_t *srcPtr = (const uint16_t *)src[0];
+
+ for (i = 0; i < srcSliceH; i++) {
+ for (j = 0; j < srcstr; j++) {
+ dstPtr[j] = av_bswap16(srcPtr[j]);
+ }
+ srcPtr += srcstr;
+ dstPtr += dststr;
+ }
+
+ return srcSliceH;
+}
+
static int palToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
int srcSliceH, uint8_t* dst[], int dstStride[])
{
if ((dstFormat == PIX_FMT_RGB32_1 || dstFormat == PIX_FMT_BGR32_1) && !isRGBA32(srcFormat))
dstPtr += ALT32_CORR;
- if (dstStride[0]*srcBpp == srcStride[0]*dstBpp && srcStride[0] > 0)
+ if (dstStride[0]*srcBpp == srcStride[0]*dstBpp && srcStride[0] > 0 && !(srcStride[0] % srcBpp))
conv(srcPtr, dstPtr + dstStride[0]*srcSliceY, srcSliceH*srcStride[0]);
else {
int i;
return srcSliceH;
}
-#define DITHER_COPY(dst, dstStride, wfunc, src, srcStride, rfunc, dithers, shift) \
+#define clip9(x) av_clip_uintp2(x, 9)
+#define clip10(x) av_clip_uintp2(x, 10)
+#define DITHER_COPY(dst, dstStride, wfunc, src, srcStride, rfunc, dithers, shift, clip) \
for (i = 0; i < height; i++) { \
const uint8_t *dither = dithers[i & 7]; \
for (j = 0; j < length - 7; j += 8) { \
- wfunc(&dst[j + 0], (rfunc(&src[j + 0]) + dither[0]) >> shift); \
- wfunc(&dst[j + 1], (rfunc(&src[j + 1]) + dither[1]) >> shift); \
- wfunc(&dst[j + 2], (rfunc(&src[j + 2]) + dither[2]) >> shift); \
- wfunc(&dst[j + 3], (rfunc(&src[j + 3]) + dither[3]) >> shift); \
- wfunc(&dst[j + 4], (rfunc(&src[j + 4]) + dither[4]) >> shift); \
- wfunc(&dst[j + 5], (rfunc(&src[j + 5]) + dither[5]) >> shift); \
- wfunc(&dst[j + 6], (rfunc(&src[j + 6]) + dither[6]) >> shift); \
- wfunc(&dst[j + 7], (rfunc(&src[j + 7]) + dither[7]) >> shift); \
+ wfunc(&dst[j + 0], clip((rfunc(&src[j + 0]) + dither[0]) >> shift)); \
+ wfunc(&dst[j + 1], clip((rfunc(&src[j + 1]) + dither[1]) >> shift)); \
+ wfunc(&dst[j + 2], clip((rfunc(&src[j + 2]) + dither[2]) >> shift)); \
+ wfunc(&dst[j + 3], clip((rfunc(&src[j + 3]) + dither[3]) >> shift)); \
+ wfunc(&dst[j + 4], clip((rfunc(&src[j + 4]) + dither[4]) >> shift)); \
+ wfunc(&dst[j + 5], clip((rfunc(&src[j + 5]) + dither[5]) >> shift)); \
+ wfunc(&dst[j + 6], clip((rfunc(&src[j + 6]) + dither[6]) >> shift)); \
+ wfunc(&dst[j + 7], clip((rfunc(&src[j + 7]) + dither[7]) >> shift)); \
} \
for (; j < length; j++) \
wfunc(&dst[j], (rfunc(&src[j]) + dither[j & 7]) >> shift); \
} else if (dst_depth < src_depth) { \
DITHER_COPY(dstPtr2, dstStride[plane]/2, wfunc, \
srcPtr2, srcStride[plane]/2, rfunc, \
- dither_8x8_1, 1); \
+ dither_8x8_1, 1, clip9); \
} else { \
COPY9_OR_10TO9_OR_10(wfunc(&dstPtr2[j], rfunc(&srcPtr2[j]))); \
}
if (src_depth == 9) { \
DITHER_COPY(dstPtr, dstStride[plane], W8, \
srcPtr2, srcStride[plane]/2, rfunc, \
- dither_8x8_1, 1); \
+ dither_8x8_1, 1, av_clip_uint8); \
} else { \
DITHER_COPY(dstPtr, dstStride[plane], W8, \
srcPtr2, srcStride[plane]/2, rfunc, \
- dither_8x8_3, 2); \
+ dither_8x8_3, 2, av_clip_uint8); \
}
if (isBE(c->srcFormat)) {
COPY9_OR_10TO8(AV_RB16);
if (dst_depth == 9) { \
DITHER_COPY(dstPtr2, dstStride[plane]/2, wfunc, \
srcPtr2, srcStride[plane]/2, rfunc, \
- dither_8x8_128, 7); \
+ dither_8x8_128, 7, clip9); \
} else { \
DITHER_COPY(dstPtr2, dstStride[plane]/2, wfunc, \
srcPtr2, srcStride[plane]/2, rfunc, \
- dither_8x8_64, 6); \
+ dither_8x8_64, 6, clip10); \
}
if (isBE(c->dstFormat)) {
if (isBE(c->srcFormat)) {
#define COPY16TO8(rfunc) \
DITHER_COPY(dstPtr, dstStride[plane], W8, \
srcPtr2, srcStride[plane]/2, rfunc, \
- dither_8x8_256, 8);
+ dither_8x8_256, 8, av_clip_uint8);
if (isBE(c->srcFormat)) {
COPY16TO8(AV_RB16);
} else {
return srcSliceH;
}
+
+#define IS_DIFFERENT_ENDIANESS(src_fmt, dst_fmt, pix_fmt) \
+ ((src_fmt == pix_fmt ## BE && dst_fmt == pix_fmt ## LE) || \
+ (src_fmt == pix_fmt ## LE && dst_fmt == pix_fmt ## BE))
+
+
void ff_get_unscaled_swscale(SwsContext *c)
{
const enum PixelFormat srcFormat = c->srcFormat;
&& (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
c->swScale= rgbToRgbWrapper;
+ /* bswap 16 bits per pixel/component packed formats */
+ if (IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_BGR444) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_BGR48) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_BGR555) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_BGR565) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_GRAY16) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_RGB444) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_RGB48) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_RGB555) ||
+ IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_RGB565))
+ c->swScale = packed_16bpc_bswap;
+
if ((usePal(srcFormat) && (
dstFormat == PIX_FMT_RGB32 ||
dstFormat == PIX_FMT_RGB32_1 ||
{
if(!isALPHA(format))
src[3]=NULL;
- if(!isPlanarYUV(format)) {
+ if (!isPlanar(format)) {
src[3]=src[2]=NULL;
if (!usePal(format))
* swscale wrapper, so we don't need to export the SwsContext.
* Assumes planar YUV to be in YUV order instead of YVU.
*/
-int sws_scale(struct SwsContext *c, const uint8_t* const srcSlice[],
+int attribute_align_arg sws_scale(struct SwsContext *c, const uint8_t* const srcSlice[],
const int srcStride[], int srcSliceY, int srcSliceH,
uint8_t* const dst[], const int dstStride[])
{