summaryrefslogtreecommitdiff
path: root/libswscale
diff options
context:
space:
mode:
Diffstat (limited to 'libswscale')
-rw-r--r--libswscale/rgb2rgb.c19
-rw-r--r--libswscale/rgb2rgb.h1
-rw-r--r--libswscale/swscale-test.c4
-rw-r--r--libswscale/swscale_unscaled.c55
4 files changed, 53 insertions, 26 deletions
diff --git a/libswscale/rgb2rgb.c b/libswscale/rgb2rgb.c
index 31ebc20a68..96559202b9 100644
--- a/libswscale/rgb2rgb.c
+++ b/libswscale/rgb2rgb.c
@@ -183,6 +183,25 @@ void rgb16tobgr32(const uint8_t *src, uint8_t *dst, int src_size)
}
}
+void rgb12to15(const uint8_t *src, uint8_t *dst, int src_size)
+{
+ const uint16_t *end;
+ uint16_t *d = (uint16_t *)dst;
+ const uint16_t *s = (const uint16_t *)src;
+ uint16_t rgb, r, g, b;
+ end = s + src_size / 2;
+ while (s < end) {
+ rgb = *s++;
+ r = rgb & 0xF00;
+ g = rgb & 0x0F0;
+ b = rgb & 0x00F;
+ r = (r << 3) | ((r & 0x800) >> 1);
+ g = (g << 2) | ((g & 0x080) >> 2);
+ b = (b << 1) | ( b >> 3);
+ *d++ = r | g | b;
+ }
+}
+
void rgb16to24(const uint8_t *src, uint8_t *dst, int src_size)
{
const uint16_t *end;
diff --git a/libswscale/rgb2rgb.h b/libswscale/rgb2rgb.h
index 4e63124977..c4479862ef 100644
--- a/libswscale/rgb2rgb.h
+++ b/libswscale/rgb2rgb.h
@@ -63,6 +63,7 @@ void rgb15to24(const uint8_t *src, uint8_t *dst, int src_size);
void rgb15tobgr16(const uint8_t *src, uint8_t *dst, int src_size);
void rgb15tobgr15(const uint8_t *src, uint8_t *dst, int src_size);
void rgb12tobgr12(const uint8_t *src, uint8_t *dst, int src_size);
+void rgb12to15(const uint8_t *src, uint8_t *dst, int src_size);
void shuffle_bytes_0321(const uint8_t *src, uint8_t *dst, int src_size);
void shuffle_bytes_1230(const uint8_t *src, uint8_t *dst, int src_size);
diff --git a/libswscale/swscale-test.c b/libswscale/swscale-test.c
index f382ce3d6a..ef6c55ce02 100644
--- a/libswscale/swscale-test.c
+++ b/libswscale/swscale-test.c
@@ -340,8 +340,8 @@ int main(int argc, char **argv)
enum PixelFormat srcFormat = PIX_FMT_NONE;
enum PixelFormat dstFormat = PIX_FMT_NONE;
uint8_t *rgb_data = av_malloc(W * H * 4);
- uint8_t *rgb_src[3] = { rgb_data, NULL, NULL };
- int rgb_stride[3] = { 4 * W, 0, 0 };
+ uint8_t *rgb_src[4] = { rgb_data, NULL, NULL, NULL };
+ int rgb_stride[4] = { 4 * W, 0, 0, 0 };
uint8_t *data = av_malloc(4 * W * H);
uint8_t *src[4] = { data, data + W * H, data + W * H * 2, data + W * H * 3 };
int stride[4] = { W, W, W, W };
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index d25c5facf4..eca377873b 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -396,17 +396,22 @@ static int planarRgbToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStr
)
/* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
-static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
- int srcSliceY, int srcSliceH, uint8_t *dst[],
- int dstStride[])
+typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int);
+static rgbConvFn findRgbConvFn(SwsContext *c)
{
const enum PixelFormat srcFormat = c->srcFormat;
const enum PixelFormat dstFormat = c->dstFormat;
- const int srcBpp = (c->srcFormatBpp + 7) >> 3;
- const int dstBpp = (c->dstFormatBpp + 7) >> 3;
const int srcId = c->srcFormatBpp;
const int dstId = c->dstFormatBpp;
- void (*conv)(const uint8_t *src, uint8_t *dst, int src_size) = NULL;
+ rgbConvFn conv = NULL;
+
+#define IS_NOT_NE(bpp, fmt) \
+ (((bpp + 7) >> 3) == 2 && \
+ (!(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_BE) != !HAVE_BIGENDIAN))
+
+ /* if this is non-native rgb444/555/565, don't handle it here. */
+ if (IS_NOT_NE(srcId, srcFormat) || IS_NOT_NE(dstId, dstFormat))
+ return NULL;
#define CONV_IS(src, dst) (srcFormat == PIX_FMT_##src && dstFormat == PIX_FMT_##dst)
@@ -428,6 +433,7 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) ||
(isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
switch (srcId | (dstId << 16)) {
+ case 0x000F000C: conv = rgb12to15; break;
case 0x000F0010: conv = rgb16to15; break;
case 0x000F0018: conv = rgb24to15; break;
case 0x000F0020: conv = rgb32to15; break;
@@ -463,6 +469,21 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
}
}
+ return conv;
+}
+
+/* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
+static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
+ int srcSliceY, int srcSliceH, uint8_t *dst[],
+ int dstStride[])
+
+{
+ const enum PixelFormat srcFormat = c->srcFormat;
+ const enum PixelFormat dstFormat = c->dstFormat;
+ const int srcBpp = (c->srcFormatBpp + 7) >> 3;
+ const int dstBpp = (c->dstFormatBpp + 7) >> 3;
+ rgbConvFn conv = findRgbConvFn(c);
+
if (!conv) {
av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
@@ -694,6 +715,8 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t *src[],
} else {
if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
length *= 2;
+ else if (!av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1)
+ length >>= 3; // monowhite/black
for (i = 0; i < height; i++) {
memcpy(dstPtr, srcPtr, length);
srcPtr += srcStride[plane];
@@ -748,24 +771,8 @@ void ff_get_unscaled_swscale(SwsContext *c)
c->swScale = bgr24ToYv12Wrapper;
/* RGB/BGR -> RGB/BGR (no dither needed forms) */
- if ( isAnyRGB(srcFormat)
- && isAnyRGB(dstFormat)
- && srcFormat != PIX_FMT_BGR8 && dstFormat != PIX_FMT_BGR8
- && srcFormat != PIX_FMT_RGB8 && dstFormat != PIX_FMT_RGB8
- && srcFormat != PIX_FMT_BGR4 && dstFormat != PIX_FMT_BGR4
- && srcFormat != PIX_FMT_RGB4 && dstFormat != PIX_FMT_RGB4
- && srcFormat != PIX_FMT_BGR4_BYTE && dstFormat != PIX_FMT_BGR4_BYTE
- && srcFormat != PIX_FMT_RGB4_BYTE && dstFormat != PIX_FMT_RGB4_BYTE
- && srcFormat != PIX_FMT_MONOBLACK && dstFormat != PIX_FMT_MONOBLACK
- && srcFormat != PIX_FMT_MONOWHITE && dstFormat != PIX_FMT_MONOWHITE
- && srcFormat != PIX_FMT_RGB48LE && dstFormat != PIX_FMT_RGB48LE
- && srcFormat != PIX_FMT_RGB48BE && dstFormat != PIX_FMT_RGB48BE
- && srcFormat != PIX_FMT_BGR48LE && dstFormat != PIX_FMT_BGR48LE
- && srcFormat != PIX_FMT_BGR48BE && dstFormat != PIX_FMT_BGR48BE
- && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)))
- && (!(av_pix_fmt_descriptors[srcFormat].flags & PIX_FMT_BE) == !HAVE_BIGENDIAN || (c->srcFormatBpp+7)/8!=2)
- && (!(av_pix_fmt_descriptors[dstFormat].flags & PIX_FMT_BE) == !HAVE_BIGENDIAN || (c->dstFormatBpp+7)/8!=2)
- )
+ if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c)
+ && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
c->swScale= rgbToRgbWrapper;
#define isByteRGB(f) (\