[FFmpeg-devel] [RFC]Don't use round when encoding png

Carl Eugen Hoyos cehoyos at ag.or.at
Sun Mar 1 12:09:28 CET 2015


On Sunday 01 March 2015 11:22:10 am Michael Niedermayer wrote:
> On Sun, Mar 01, 2015 at 09:44:30AM +0100, Carl Eugen Hoyos wrote:
> > Attached untested patch should fix compilation on broken platforms.
> > We don't use round() currently because it appears less portable than
> > lrintf().

> yes reducing float code usage should be fine, less potential to
> cause problems with regression tests

New patch attached.

Please review, Carl Eugen
-------------- next part --------------
diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index 9fd8eef..b6eedde 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -231,78 +231,77 @@ static int png_write_row(PNGEncContext *s, const uint8_t *data, int size)
     return 0;
 }
 
-#define AV_WB32_PNG(buf, n) (AV_WB32(buf, round((n) * 100000)))
 static int png_get_chrm(enum AVColorPrimaries prim,  uint8_t *buf)
 {
-    double rx, ry, gx, gy, bx, by, wx = 0.3127, wy = 0.3290;
+    int rx, ry, gx, gy, bx, by, wx = 312700, wy = 329000;
     switch (prim) {
         case AVCOL_PRI_BT709:
-            rx = 0.640; ry = 0.330;
-            gx = 0.300; gy = 0.600;
-            bx = 0.150; by = 0.060;
+            rx = 64000; ry = 33000;
+            gx = 30000; gy = 60000;
+            bx = 15000; by =  6000;
             break;
         case AVCOL_PRI_BT470M:
-            rx = 0.670; ry = 0.330;
-            gx = 0.210; gy = 0.710;
-            bx = 0.140; by = 0.080;
-            wx = 0.310; wy = 0.316;
+            rx = 67000; ry = 33000;
+            gx = 21000; gy = 71000;
+            bx = 14000; by =  8000;
+            wx = 31000; wy = 31600;
             break;
         case AVCOL_PRI_BT470BG:
-            rx = 0.640; ry = 0.330;
-            gx = 0.290; gy = 0.600;
-            bx = 0.150; by = 0.060;
+            rx = 64000; ry = 33000;
+            gx = 29000; gy = 60000;
+            bx = 15000; by = 06000;
             break;
         case AVCOL_PRI_SMPTE170M:
         case AVCOL_PRI_SMPTE240M:
-            rx = 0.630; ry = 0.340;
-            gx = 0.310; gy = 0.595;
-            bx = 0.155; by = 0.070;
+            rx = 63000; ry = 34000;
+            gx = 31000; gy = 59500;
+            bx = 15500; by =  7000;
             break;
         case AVCOL_PRI_BT2020:
-            rx = 0.708; ry = 0.292;
-            gx = 0.170; gy = 0.797;
-            bx = 0.131; by = 0.046;
+            rx = 70800; ry = 29200;
+            gx = 17000; gy = 79700;
+            bx = 13100; by =  4600;
             break;
         default:
             return 0;
     }
 
-    AV_WB32_PNG(buf     , wx); AV_WB32_PNG(buf + 4 , wy);
-    AV_WB32_PNG(buf + 8 , rx); AV_WB32_PNG(buf + 12, ry);
-    AV_WB32_PNG(buf + 16, gx); AV_WB32_PNG(buf + 20, gy);
-    AV_WB32_PNG(buf + 24, bx); AV_WB32_PNG(buf + 28, by);
+    AV_WB32(buf     , wx); AV_WB32(buf + 4 , wy);
+    AV_WB32(buf + 8 , rx); AV_WB32(buf + 12, ry);
+    AV_WB32(buf + 16, gx); AV_WB32(buf + 20, gy);
+    AV_WB32(buf + 24, bx); AV_WB32(buf + 28, by);
     return 1;
 }
 
 static int png_get_gama(enum AVColorTransferCharacteristic trc, uint8_t *buf)
 {
-    double gamma;
+    int gamma;
     switch (trc) {
         case AVCOL_TRC_BT709:
         case AVCOL_TRC_SMPTE170M:
         case AVCOL_TRC_SMPTE240M:
         case AVCOL_TRC_BT1361_ECG:
         case AVCOL_TRC_BT2020_10:
         case AVCOL_TRC_BT2020_12:
             /* these share a segmented TRC, but gamma 1.961 is a close
               approximation, and also more correct for decoding content */
-            gamma = 1.961;
+            gamma = 50994; // 100000 / 1.961
             break;
         case AVCOL_TRC_GAMMA22:
         case AVCOL_TRC_IEC61966_2_1:
-            gamma = 2.2;
+            gamma = 45455; // 100000 / 2.2
             break;
         case AVCOL_TRC_GAMMA28:
-            gamma = 2.8;
+            gamma = 35714; // 100000 / 2.8
             break;
         case AVCOL_TRC_LINEAR:
-            gamma = 1.0;
+            gamma = 100000;
             break;
         default:
             return 0;
     }
 
-    AV_WB32_PNG(buf, 1.0 / gamma);
+    AV_WB32(buf, gamma);
     return 1;
 }
 


More information about the ffmpeg-devel mailing list