From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Manuel Giraud via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#74476: [PATCH] Explore JPEG loading without quantization Date: Fri, 22 Nov 2024 15:53:18 +0100 Message-ID: <871pz39v6p.fsf@ledu-giraud.fr> Reply-To: Manuel Giraud Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="21416"; mail-complaints-to="usenet@ciao.gmane.io" To: 74476@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Fri Nov 22 15:54:25 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1tEV3A-0005Oi-C5 for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 22 Nov 2024 15:54:24 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tEV2q-0002lY-Pz; Fri, 22 Nov 2024 09:54:04 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tEV2p-0002lF-BK for bug-gnu-emacs@gnu.org; Fri, 22 Nov 2024 09:54:03 -0500 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tEV2p-0002Pj-0F for bug-gnu-emacs@gnu.org; Fri, 22 Nov 2024 09:54:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:Date:From:To:Subject; bh=wyoMHWpWpMdKmfWis36VuQbuj6a4QV1SiMqkTNjpPrM=; b=jHs60b2UQsCVAqRBINb1RjroNXaVKQTiBYMgdbUIQtF8hlKRs+rTm4vz+D7R7ORNwIz2gLOwQY4xVlJ0Yru/bfHivQlZuRpTVbhmrgciUsRh+z3gwq38yy1HpvEQBhdyzLizFBFs3W2wNgO8eVYRZO9psRiSlD7Bo4mZmmFjSXzlXv+83umbuds5++wrOcwtsGfVCnyCBPGufkb1qQ59Z5K1fokS4WWgg8lihdN3c0zV8B4Nr7fTRolCe6emOBjcXnfBmmG/5upKZl7ef+0Zc1Mz4uM7Q5NingCJqRyHyDB7jiB4zTwxQr4rq+46rauAQDmf+iRM9xkrtSzRtnyYoQ==; Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tEV2o-00067T-03 for bug-gnu-emacs@gnu.org; Fri, 22 Nov 2024 09:54:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Manuel Giraud Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 22 Nov 2024 14:54:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 74476 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.173228722723497 (code B ref -1); Fri, 22 Nov 2024 14:54:01 +0000 Original-Received: (at submit) by debbugs.gnu.org; 22 Nov 2024 14:53:47 +0000 Original-Received: from localhost ([127.0.0.1]:53839 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tEV2Y-00066t-JQ for submit@debbugs.gnu.org; Fri, 22 Nov 2024 09:53:47 -0500 Original-Received: from lists.gnu.org ([209.51.188.17]:36794) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tEV2W-00066i-Gz for submit@debbugs.gnu.org; Fri, 22 Nov 2024 09:53:45 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tEV2U-0002kO-22 for bug-gnu-emacs@gnu.org; Fri, 22 Nov 2024 09:53:42 -0500 Original-Received: from ledu-giraud.fr ([51.159.28.247]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tEV2G-0002Nn-DI for bug-gnu-emacs@gnu.org; Fri, 22 Nov 2024 09:53:40 -0500 DKIM-Signature: v=1; a=ed25519-sha256; c=simple/simple; s=ed25519; bh=XqMqL2mo O/8FTZgnUNYN1ncTJ8E1Tf4PhQaJ9/trGJ0=; h=date:subject:to:from; d=ledu-giraud.fr; b=NS9zi/oZc4SVrzAFoYTtoLnp+qN7zlOiyuFQpTx6G8XFtK0LGF akyPWGUWsoaA+gqp0KRHLO//S7p56KtEeFAg== DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; s=rsa; bh=XqMqL2moO/8FTZgn UNYN1ncTJ8E1Tf4PhQaJ9/trGJ0=; h=date:subject:to:from; d=ledu-giraud.fr; b=cS7RtNLw+7vrSKSz5CJAUoWCgdXyqVESDZd774pgSxgyEQGsSE lmk/EUxtv+WG7tM8xh3u+aEOIS41r9ijvCQp6D0AqOiK0nQZDV+9wpnSTO6poQ8rzj58xu rmeLzwwGD9yY2XRdI1A8L3Nw2WJBl6H5bI63Tu7ljmOezHetrlyoe+8x2UIOwxTZxTJtnr gKo+g9RTeZznszaCfbiPk6ZKabKImMYFKPVJ9jN0IIi5NDtI9jerVLIfRgiuHD0KEx7AjY rSD+ayaZ+7UjPzGPQBBuNQ5hcE2lwl1KarB6u/y/EsfICXpPoYPlxxbFXWk91+tyVUabq0 XV/xxbDoy+Tw== Original-Received: from computer ( [10.1.1.1]) by ledu-giraud.fr (OpenSMTPD) with ESMTPSA id d820dd9f (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO) for ; Fri, 22 Nov 2024 15:53:19 +0100 (CET) Received-SPF: pass client-ip=51.159.28.247; envelope-from=manuel@ledu-giraud.fr; helo=ledu-giraud.fr X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:295796 Archived-At: --=-=-= Content-Type: text/plain Tags: patch Hi, While trying to speed up "emacs as an image viewer", I found that emacs is using libjpeg with color quantization and it seems that removing this quantization could speed up JPEG loading a bit. My simple limited benchmark: - M-: (clear-image-cache) - Open an image in folder with some large enough pictures in it (4000x3000 here) - M-: (benchmark-run 10 (image-next-file 1)) Here are the results I get: without this path: (5.415405491 1 0.09232176400000025) with: (3.079911418 1 0.0751190459999993) I don't think that this patch could be applied as is (it is rather ugly). And I also think that I probably have missed some (many?) use case (where color quantization is mandatory). But I'm submitting this patch anyway as a conversation starter on the subject. Thanks, In GNU Emacs 31.0.50 (build 9, x86_64-unknown-openbsd7.6, X toolkit) of 2024-11-22 built on computer Repository revision: c66c0942ea9ac10e6d6324e472150de403a03b69 Repository branch: master Windowing system distributor 'The X.Org Foundation', version 11.0.12101014 System Description: OpenBSD computer 7.6 GENERIC.MP#437 amd64 Configured using: 'configure CC=egcc CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib MAKEINFO=gmakeinfo --prefix=/home/manuel/emacs --bindir=/home/manuel/bin --with-x-toolkit=lucid --with-toolkit-scroll-bars=no --without-cairo --without-compress-install' --=-=-= Content-Type: text/patch Content-Disposition: attachment; filename=0001-Explore-JPEG-loading-without-quantization.patch >From e360545b65427d6f0eec05cdeb26b8a05d8a0d61 Mon Sep 17 00:00:00 2001 From: Manuel Giraud Date: Thu, 21 Nov 2024 17:19:59 +0100 Subject: [PATCH] Explore JPEG loading without quantization --- src/image.c | 63 +++++++++++++---------------------------------------- 1 file changed, 15 insertions(+), 48 deletions(-) diff --git a/src/image.c b/src/image.c index db7f6acd171..374d2f9c454 100644 --- a/src/image.c +++ b/src/image.c @@ -8949,9 +8949,9 @@ jpeg_load_body (struct frame *f, struct image *img, FILE *fp = NULL; JSAMPARRAY buffer; int row_stride, x, y; - int width, height; - int i, ir, ig, ib; - unsigned long *colors; + int width, height, ncomp; + int i, off; + unsigned long color; Emacs_Pix_Container volatile ximg_volatile = NULL; /* Open the JPEG file. */ @@ -9049,12 +9049,11 @@ jpeg_load_body (struct frame *f, struct image *img, jpeg_read_header (&mgr->cinfo, 1); - /* Customize decompression so that color quantization will be used. - Start decompression. */ - mgr->cinfo.quantize_colors = 1; + /* Start decompression. */ jpeg_start_decompress (&mgr->cinfo); width = img->width = mgr->cinfo.output_width; height = img->height = mgr->cinfo.output_height; + ncomp = mgr->cinfo.output_components; if (!check_image_size (f, width, height)) { @@ -9073,53 +9072,22 @@ jpeg_load_body (struct frame *f, struct image *img, sys_longjmp (mgr->setjmp_buffer, 1); } - /* Allocate colors. When color quantization is used, - mgr->cinfo.actual_number_of_colors has been set with the number of - colors generated, and mgr->cinfo.colormap is a two-dimensional array - of color indices in the range 0..mgr->cinfo.actual_number_of_colors. - No more than 255 colors will be generated. */ - USE_SAFE_ALLOCA; - { - if (mgr->cinfo.out_color_components > 2) - ir = 0, ig = 1, ib = 2; - else if (mgr->cinfo.out_color_components > 1) - ir = 0, ig = 1, ib = 0; - else - ir = 0, ig = 0, ib = 0; - - /* Use the color table mechanism because it handles colors that - cannot be allocated nicely. Such colors will be replaced with - a default color, and we don't have to care about which colors - can be freed safely, and which can't. */ - init_color_table (); - SAFE_NALLOCA (colors, 1, mgr->cinfo.actual_number_of_colors); - - for (i = 0; i < mgr->cinfo.actual_number_of_colors; ++i) - { - /* Multiply RGB values with 255 because X expects RGB values - in the range 0..0xffff. */ - int r = mgr->cinfo.colormap[ir][i] << 8; - int g = mgr->cinfo.colormap[ig][i] << 8; - int b = mgr->cinfo.colormap[ib][i] << 8; - colors[i] = lookup_rgb_color (f, r, g, b); - } - -#ifdef COLOR_TABLE_SUPPORT - /* Remember those colors actually allocated. */ - img->colors = colors_in_color_table (&img->ncolors); - free_color_table (); -#endif /* COLOR_TABLE_SUPPORT */ - } - /* Read pixels. */ - row_stride = width * mgr->cinfo.output_components; + row_stride = width * ncomp; buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo, JPOOL_IMAGE, row_stride, 1); for (y = 0; y < height; ++y) { jpeg_read_scanlines (&mgr->cinfo, buffer, 1); - for (x = 0; x < mgr->cinfo.output_width; ++x) - PUT_PIXEL (ximg, x, y, colors[buffer[0][x]]); + for (x = 0; x < width; ++x) + { + color = 0; + off = x * ncomp; + /* XXX I suck at bit twiddling. */ + for (i = 0; i < ncomp; ++i) + color += (buffer[0][off + i] << ((ncomp - 1 - i) * 8)); + PUT_PIXEL (ximg, x, y, color); + } } /* Clean up. */ @@ -9135,7 +9103,6 @@ jpeg_load_body (struct frame *f, struct image *img, /* Put ximg into the image. */ image_put_x_image (f, img, ximg, 0); - SAFE_FREE (); return 1; } -- 2.47.0 --=-=-= Content-Type: text/plain -- Manuel Giraud --=-=-=--