soliloque has proposed merging lp:~soliloque/simple-scan/fastpdf into 
lp:simple-scan.

Commit message:
Hasten the save_pdf method

Requested reviews:
  Robert Ancell (robert-ancell)

For more details, see:
https://code.launchpad.net/~soliloque/simple-scan/fastpdf/+merge/322610

Sorry, the diff is pretty hard to read.

Saving pdf currently take a long time, in part because it currently encode each 
page two times: one time with zlib, then with jpeg, and finally discard the 
biggest version. However this is mostly useless because in all test I did, the 
ZLIB compression was choosen when using the "Text" setting and JPEG compression 
when using the "Photo" setting.

I modified save_pdf so when using "Text" setting, it directly encode with zlib 
and when using "Photo" setting, it directly encode with jpeg. As the zlib 
algorithm take longer when not compressing effectively, the speedup can be very 
high: with only one page and an empty flatbed using "Photo" setting, the 
book.save method take right now 26 seconds on my computer, vs 0,1 seconds with 
this change.


-- 
Your team Simple Scan Development Team is subscribed to branch lp:simple-scan.
=== modified file 'src/book.vala'
--- src/book.vala	2017-03-29 09:40:01 +0000
+++ src/book.vala	2017-04-16 15:04:24 +0000
@@ -341,152 +341,119 @@
             unowned uint8[] pixels = image.get_pixels ();
             var page_width = width * 72.0 / page.dpi;
             var page_height = height * 72.0 / page.dpi;
-
-            int depth = 8;
-            string color_space = "DeviceRGB";
-            string? filter = null;
+            int depth;
+            string color_space;
+            string filter;
             char[] width_buffer = new char[double.DTOSTR_BUF_SIZE];
             char[] height_buffer = new char[double.DTOSTR_BUF_SIZE];
             uint8[] data;
+
             if (page.is_color)
             {
                 depth = 8;
                 color_space = "DeviceRGB";
-                var data_length = height * width * 3;
-                data = new uint8[data_length];
-                for (var row = 0; row < height; row++)
-                {
-                    var in_offset = row * image.rowstride;
-                    var out_offset = row * width * 3;
-                    for (var x = 0; x < width; x++)
-                    {
-                        var in_o = in_offset + x*3;
-                        var out_o = out_offset + x*3;
-
-                        data[out_o] = pixels[in_o];
-                        data[out_o+1] = pixels[in_o+1];
-                        data[out_o+2] = pixels[in_o+2];
-                    }
-                }
+                data = compress_jpeg (image, quality, page.dpi);
+                filter = "DCTDecode"; /* JPEG compression applied to color image data */
             }
-            else if (page.depth == 2)
+            else
             {
-                int shift_count = 6;
-                depth = 2;
                 color_space = "DeviceGray";
-                var data_length = height * ((width * 2 + 7) / 8);
-                data = new uint8[data_length];
-                var offset = 0;
-                for (var row = 0; row < height; row++)
+                if (page.depth == 2)
                 {
-                    /* Pad to the next line */
-                    if (shift_count != 6)
-                    {
-                        offset++;
-                        shift_count = 6;
-                    }
-
-                    var in_offset = row * image.rowstride;
-                    for (var x = 0; x < width; x++)
-                    {
-                        /* Clear byte */
-                        if (shift_count == 6)
-                            data[offset] = 0;
-
-                        /* Set bits */
-                        var p = pixels[in_offset + x*3];
-                        if (p >= 192)
-                            data[offset] |= 3 << shift_count;
-                        else if (p >= 128)
-                            data[offset] |= 2 << shift_count;
-                        else if (p >= 64)
-                            data[offset] |= 1 << shift_count;
-
-                        /* Move to the next position */
-                        if (shift_count == 0)
+                    int shift_count = 6;
+                    depth = 2;
+                    var data_length = height * ((width * 2 + 7) / 8);
+                    data = new uint8[data_length];
+                    var offset = 0;
+                    for (var row = 0; row < height; row++)
+                    {
+                        /* Pad to the next line */
+                        if (shift_count != 6)
                         {
                             offset++;
                             shift_count = 6;
                         }
-                        else
-                            shift_count -= 2;
+
+                        var in_offset = row * image.rowstride;
+                        for (var x = 0; x < width; x++)
+                        {
+                            /* Clear byte */
+                            if (shift_count == 6)
+                                data[offset] = 0;
+
+                            /* Set bits */
+                            var p = pixels[in_offset + x*3];
+                            if (p >= 192)
+                                data[offset] |= 3 << shift_count;
+                            else if (p >= 128)
+                                data[offset] |= 2 << shift_count;
+                            else if (p >= 64)
+                                data[offset] |= 1 << shift_count;
+
+                            /* Move to the next position */
+                            if (shift_count == 0)
+                            {
+                                offset++;
+                                shift_count = 6;
+                            }
+                            else
+                                shift_count -= 2;
+                        }
                     }
                 }
-            }
-            else if (page.depth == 1)
-            {
-                int mask = 0x80;
-
-                depth = 1;
-                color_space = "DeviceGray";
-                var data_length = height * ((width + 7) / 8);
-                data = new uint8[data_length];
-                var offset = 0;
-                for (var row = 0; row < height; row++)
+                else if (page.depth == 1)
                 {
-                    /* Pad to the next line */
-                    if (mask != 0x80)
-                    {
-                        offset++;
-                        mask = 0x80;
-                    }
-
-                    var in_offset = row * image.rowstride;
-                    for (var x = 0; x < width; x++)
-                    {
-                        /* Clear byte */
-                        if (mask == 0x80)
-                            data[offset] = 0;
-
-                        /* Set bit */
-                        if (pixels[in_offset+x*3] != 0)
-                            data[offset] |= (uint8) mask;
-
-                        /* Move to the next bit */
-                        mask >>= 1;
-                        if (mask == 0)
+                    int mask = 0x80;
+
+                    depth = 1;
+                    var data_length = height * ((width + 7) / 8);
+                    data = new uint8[data_length];
+                    var offset = 0;
+                    for (var row = 0; row < height; row++)
+                    {
+                        /* Pad to the next line */
+                        if (mask != 0x80)
                         {
                             offset++;
                             mask = 0x80;
                         }
+
+                        var in_offset = row * image.rowstride;
+                        for (var x = 0; x < width; x++)
+                        {
+                            /* Clear byte */
+                            if (mask == 0x80)
+                                data[offset] = 0;
+
+                            /* Set bit */
+                            if (pixels[in_offset+x*3] != 0)
+                                data[offset] |= (uint8) mask;
+
+                            /* Move to the next bit */
+                            mask >>= 1;
+                            if (mask == 0)
+                            {
+                                offset++;
+                                mask = 0x80;
+                            }
+                        }
                     }
                 }
-            }
-            else
-            {
-                depth = 8;
-                color_space = "DeviceGray";
-                var data_length = height * width;
-                data = new uint8 [data_length];
-                for (var row = 0; row < height; row++)
-                {
-                    var in_offset = row * image.rowstride;
-                    var out_offset = row * width;
-                    for (var x = 0; x < width; x++)
-                        data[out_offset+x] = pixels[in_offset+x*3];
-                }
-            }
-
-            /* Compress data */
-            var compressed_data = compress_zlib (data);
-            if (compressed_data != null)
-            {
-                /* Try if JPEG compression is better */
-                if (depth > 1)
-                {
-                    var jpeg_data = compress_jpeg (image, quality, page.dpi);
-                    if (jpeg_data.length < compressed_data.length)
+                else
+                {
+                    depth = 8;
+                    var data_length = height * width;
+                    data = new uint8 [data_length];
+                    for (var row = 0; row < height; row++)
                     {
-                        filter = "DCTDecode";
-                        data = jpeg_data;
+                        var in_offset = row * image.rowstride;
+                        var out_offset = row * width;
+                        for (var x = 0; x < width; x++)
+                            data[out_offset+x] = pixels[in_offset+x*3];
                     }
                 }
-
-                if (filter == null)
-                {
-                    filter = "FlateDecode";
-                    data = compressed_data;
-                }
+                data = compress_zlib (data);
+                filter = "FlateDecode"; /* ZLIB compression applied to gray image data */
             }
 
             /* Page */
@@ -528,7 +495,7 @@
             writer.start_object (struct_tree_root_number);
             writer.write_string ("%u 0 obj\n".printf (struct_tree_root_number));
             writer.write_string ("<<\n");
-            writer.write_string ("/Type /StructTreeRoot\n");            
+            writer.write_string ("/Type /StructTreeRoot\n");
             writer.write_string (">>\n");
             writer.write_string ("endobj\n");
 

_______________________________________________
Mailing list: https://launchpad.net/~simple-scan-team
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~simple-scan-team
More help   : https://help.launchpad.net/ListHelp

Reply via email to