From 92e94009b2b4db0db9a707f7e33c88b7b1fae5cd Mon Sep 17 00:00:00 2001 From: gitlost Date: Wed, 29 Jul 2026 17:39:01 +0100 Subject: [PATCH] raster: base `draw_mp_circle()` on `plotCircle()` from https://zingl.github.io/bresenham.c by Zingl Alois rather than RosettaCode one, better at small scales plus simplifies licence/attribution issues; fix licence/attribution issues for `plot_hexline()` also which is actually based on `plotLine()` in zingl code (ticket #357, props stefan6419846) debian/copyright: update with above --- backend/raster.c | 45 ++++++++---------- backend/tests/data/png/maxicode_0.5.png | Bin 925 -> 926 bytes .../tests/data/png/maxicode_0.7_wsp3_box1.png | Bin 1497 -> 1498 bytes debian/copyright | 7 +++ 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/backend/raster.c b/backend/raster.c index 5ab86838..96b6019e 100644 --- a/backend/raster.c +++ b/backend/raster.c @@ -30,6 +30,10 @@ */ /* SPDX-License-Identifier: BSD-3-Clause */ +/* Contains routines adapted from https://zingl.github.io/bresenham.c + Copyright (c) 2020 zingl */ +/* SPDX-License-Identifier: MIT */ + #include #include @@ -580,31 +584,25 @@ static void draw_mp_circle_lines(unsigned char *pixelbuf, const int image_width, /* Draw disc using Midpoint Circle Algorithm. Using this for MaxiCode rather than `draw_circle()` because it gives a * flatter circumference with no single pixel peaks, similar to Figures J3 and J6 in ISO/IEC 16023:2000. - * Taken from https://rosettacode.org/wiki/Bitmap/Midpoint_circle_algorithm#C - * "Content is available under GNU Free Documentation License 1.2 unless otherwise noted." - * https://www.gnu.org/licenses/old-licenses/fdl-1.2.html */ + * Following adapted from `plotCircle()` in https://zingl.github.io/bresenham.c */ static void draw_mp_circle(unsigned char *pixelbuf, const int image_width, const int image_height, - const int x0, const int y0, const int r, const int fill) { - /* Using top RHS octant from (0, r) going clockwise, so fast direction is x (i.e. always incremented) */ - int f = 1 - r; - int ddF_x = 0; - int ddF_y = -2 * r; - int x = 0; - int y = r; + const int x0, const int y0, int r, const int fill) { + int x = -r; + int y = 0; + int err = 2 - 2 * r; /* Bottom left to top right */ + + do { + draw_mp_circle_lines(pixelbuf, image_width, image_height, x0, y0, x, y, fill); + r = err; + if (r <= y) { + err += ++y * 2 + 1; + } + if (r > x || err > y) { + err += ++x * 2 + 1; + } + } while (x < 0); draw_mp_circle_lines(pixelbuf, image_width, image_height, x0, y0, x, y, fill); - - while (x < y) { - if (f >= 0) { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x + 1; - draw_mp_circle_lines(pixelbuf, image_width, image_height, x0, y0, x, y, fill); - } } /* Draw central bullseye finder in Maxicode symbols */ @@ -651,8 +649,7 @@ static void draw_hexagon(unsigned char *pixelbuf, const int image_width, const i } /* Bresenham's line algorithm https://en.wikipedia.org/wiki/Bresenham's_line_algorithm - * Creative Commons Attribution-ShareAlike License - * https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License */ + * Following adapted from `plotLine()` in https://zingl.github.io/bresenham.c */ static void plot_hexline(unsigned char *scaled_hexagon, const int hex_width, const int hex_height, int start_x, int start_y, const int end_x, const int end_y) { const int dx = abs(end_x - start_x); diff --git a/backend/tests/data/png/maxicode_0.5.png b/backend/tests/data/png/maxicode_0.5.png index 0894d767387287fa9810a6e653b8e654e9a037a7..af579ce13cb3677c14dc782e3324f7f79c9b3c5b 100644 GIT binary patch delta 860 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 Hu0mjfCT5Db delta 1295 zcmV+q1@QXX3)u^hHUW;2HzR+=R`3Jl8t_XP<^dv~=3?J{i(nsMrJN7a=($T#Bg$#H>u_ke&%U5e>ng7EftFeFo(j;=tqAE!N2_avU-2} z>w6|3VY+fkKOY@3fQxsy^CqV#Id0K8K<7L-L2~n~c@)g%xRPnKeFmNfzmbJ&Idrq#Z9C-j|@YyUisLhIcniM}`dG(heRrw`t-$$6&d;>Y*j(54{i~ zvby{NNSDjfNj;dhjI)1BU>Y?L-hz3{a3nT&S8U{}WjLP4h78~WcpTo6PemEwkrqdt zC2FI`QHMxv^dK1pGJs3>fNEn^Z}a*6AVv^1riK`ysEmRb0jDCOSwoD6H zo`^vCDUe<+B5Kg9DSPB>BN0lPM=}JJTH^L}^0bWL<}czVce4FIgoGC>MC0OARc7NN zwC)6WPJUGt;A{X`^0Zq=OPq1p8H81JvE~5Mr8n9pSYyR#%_I$^D*P(#g}AuHI=4X- z7aw1Sg^dfV8@hjZ2=KrC5>IR*w9e2MCl7Hc_kt_Tu1JtuEYhHa59IN36|zRJVciQ^ z(E%)aAWnX9t11sSCKsh{`!cAiGT1-I_nq2XDT-5uWpD{HEEGHSuF@rRDRa;vEH^t< za|6lO*ciBd5d1tHRAE9C7eAvjdMr#XO6!7s>E`$kCL({Kbw*tW!DAVeK~}0--cTtB zHpK!RDpf~dgXC*;s1Fhf$i)JwxrBcHvDg%USh&<$7y4NlJR&3#osx0u{516OAomE7 z`eM{|L57gRCx}$3%jZCPxvqfIx^x8Yy(sUxC;dQon)D^5n{1UJbXceq2l+LK(7IlTP|WKP>Ol=avib)+2?#Vq{GG1 zykaFz9`*H&=bSsOp6-*voBFkpAp^LO*2R<4m!^4*mo%^2#Ks)6X&9gQ%)dQ#r=gdo z?R@2%^Sv!(BS3!41wFcp@23&!0XMG)6gj+jHycl{y?N9Uh?THSB4Lq6?Jkq)1Q8K; z5&DpznV|CBkjSB9plRKilM4k#e^Qm;9k&tO?!04)*DYEex7ytMOsX&EFLN|p{nATq zcPV$sDb5NFPebWtIxb`Y7k7ynsGbGgeud*R_7+jHZ^aRpwmg5KQN?U7zU64e5v=Md z4h=jOEAd@PD@ewG4B$fZEMO5w<80ValB(nA|M*Se-=;GwwP}Zjw*UYD2>?k&PDHLk FV1lQEW+wmu diff --git a/debian/copyright b/debian/copyright index 96f1fbd2..b7b93fbf 100644 --- a/debian/copyright +++ b/debian/copyright @@ -115,6 +115,13 @@ Copyright: Copyright (C) 2004 (Grandzebu). License: BSD-3-Clause and GPL-2.0-or-later +Files: + backend/raster.c +Copyright: + Copyright (C) 2008-2026 Robin Stuart + Copyright (c) 2020 zingl +License: BSD-3-Clause and MIT + Files: docs/lua-crossrefs/lua-crossrefs.lua getopt/*