I've checked all numbers in dither_scale table and most are OK. Wrong numbers are for dither [from 11-bit to 8-bit are OK, my bad in copy numbers] from 16-bit to 15-bit (overflow in signed multiply -- undefined behavior; now impossible conversion).
I decided to simplify dither_scale table and write the numbers in form that you at once see that all numbers are optimal (and easy to change if you change dithers table).
nevcairiel or richardpl -- please review this patch:
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index ba3d688..8bc9ba6 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -110,22 +110,19 @@ DECLARE_ALIGNED(8, static const uint8_t, dithers)[8][8][8]={
{ 112, 16,104, 8,118, 22,110, 14,},
}};
-static const uint16_t dither_scale[15][16]={
-{ 2, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,},
-{ 2, 3, 7, 7, 13, 13, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,},
-{ 3, 3, 4, 15, 15, 29, 57, 57, 57, 113, 113, 113, 113, 113, 113, 113,},
-{ 3, 4, 4, 5, 31, 31, 61, 121, 241, 241, 241, 241, 481, 481, 481, 481,},
-{ 3, 4, 5, 5, 6, 63, 63, 125, 249, 497, 993, 993, 993, 993, 993, 1985,},
-{ 3, 5, 6, 6, 6, 7, 127, 127, 253, 505, 1009, 2017, 4033, 4033, 4033, 4033,},
-{ 3, 5, 6, 7, 7, 7, 8, 255, 255, 509, 1017, 2033, 4065, 8129,16257,16257,},
-{ 3, 5, 6, 8, 8, 8, 8, 9, 511, 511, 1021, 2041, 4081, 8161,16321,32641,},
-{ 3, 5, 7, 8, 9, 9, 9, 9, 10, 1023, 1023, 2045, 4089, 8177,16353,32705,},
-{ 3, 5, 7, 8, 10, 10, 10, 10, 10, 11, 2047, 2047, 4093, 8185,16369,32737,},
-{ 3, 5, 7, 8, 10, 11, 11, 11, 11, 11, 12, 4095, 4095, 8189,16377,32753,},
-{ 3, 5, 7, 9, 10, 12, 12, 12, 12, 12, 12, 13, 8191, 8191,16381,32761,},
-{ 3, 5, 7, 9, 10, 12, 13, 13, 13, 13, 13, 13, 14,16383,16383,32765,},
-{ 3, 5, 7, 9, 10, 12, 14, 14, 14, 14, 14, 14, 14, 15,32767,32767,},
-{ 3, 5, 7, 9, 11, 12, 14, 15, 15, 15, 15, 15, 15, 15, 16,65535,},
+/* Numbers 1, 3, 7, 15, 31, 63, 63, 126 in table dither_scale are from
+ * maximum values in diters[0], dithers[1], ..., dithers[7] table.
+ * If you change dithers table please update these numbers.
+ */
+static const uint16_t dither_scale[8][8]={
+{ ((1<<24)-1)/(511+1), ((1<<25)-1)/(1023+3), ((1<<26)-1)/(2047+7), ((1<<27)-1)/(4095+15), ((1<<28)-1)/(8191+31), ((1<<29)-1)/(16383+63), ((1<<30)-1)/(32767+63), ((1u<<31)-1)/(65535+126),},
+{ 0, ((1<<25)-1)/(1023+1), ((1<<26)-1)/(2047+3), ((1<<27)-1)/(4095+ 7), ((1<<28)-1)/(8191+15), ((1<<29)-1)/(16383+31), ((1<<30)-1)/(32767+63), ((1u<<31)-1)/(65535+ 63),},
+{ 0, 0, ((1<<26)-1)/(2047+1), ((1<<27)-1)/(4095+ 3), ((1<<28)-1)/(8191+ 7), ((1<<29)-1)/(16383+15), ((1<<30)-1)/(32767+31), ((1u<<31)-1)/(65535+ 63),},
+{ 0, 0, 0, ((1<<27)-1)/(4095+ 1), ((1<<28)-1)/(8191+ 3), ((1<<29)-1)/(16383+ 7), ((1<<30)-1)/(32767+15), ((1u<<31)-1)/(65535+ 31),},
+{ 0, 0, 0, 0, ((1<<28)-1)/(8191+ 1), ((1<<29)-1)/(16383+ 3), ((1<<30)-1)/(32767+ 7), ((1u<<31)-1)/(65535+ 15),},
+{ 0, 0, 0, 0, 0, ((1<<29)-1)/(16383+ 1), ((1<<30)-1)/(32767+ 3), ((1u<<31)-1)/(65535+ 7),},
+{ 0, 0, 0, 0, 0, 0, ((1<<30)-1)/(32767+ 1), ((1u<<31)-1)/(65535+ 3),},
+{ 0, 0, 0, 0, 0, 0, 0, ((1u<<31)-1)/(65535+ 1),},
};
@@ -1485,10 +1482,10 @@ static int packedCopyWrapper(SwsContext *c, const uint8_t *src[],
}
#define DITHER_COPY(dst, dstStride, src, srcStride, bswap, dbswap)\
- uint16_t scale= dither_scale[dst_depth-1][src_depth-1];\
- int shift= src_depth-dst_depth + dither_scale[src_depth-2][dst_depth-1];\
+ uint16_t scale= dither_scale[dst_depth-8][src_depth-9];\
+ int shift= src_depth-dst_depth + 15;\
for (i = 0; i < height; i++) {\
- const uint8_t *dither= dithers[src_depth-9][i&7];\
+ const uint8_t *dither= dithers[src_depth-dst_depth-1][i&7];\
for (j = 0; j < length-7; j+=8){\
dst[j+0] = dbswap((bswap(src[j+0]) + dither[0])*scale>>shift);\
dst[j+1] = dbswap((bswap(src[j+1]) + dither[1])*scale>>shift);\
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.