o5-Q;YoOSq(a89mCDf%CgGK!D3S>Kb
zDBSidfXW-KyK$S#p=>>jqLJ~)Qcce6yQprCy1ef2rL>qN-U98K9x*>%fsO3GezU1D
zRzJMqscP3E)gd>OhjC*-QIH8!dfkvi%s;mWw26>01yFpWnKy1b-^0Wk?l^2488?40a|Y`s?)Co6yzDfeym{j2u-xaR!l_lK8#HEpSjau~L5Lq4xj4x53)4wPX&)VqXn
zp#oT!vpJmdBpOKMOtQ2d+kUd^E#
zi5U#owWQ1QEv20a;5HQUYH@gi1ErJ?G5@evPylOGZr$y_$y{U1GhgOVA~A^pyOuZ4
zJM?y*jyvTcuPac@)5vEq?XZ_p0E@+a`_JE#ZG1-mkmik>4J#hgW!LiNd57@Mb8)9U
z#amFyqG$vM504vCS
zdliQYy_A7r7|Zv6hRdppd_gW_cM3fpZn`ix#C
zkRQJtRw0|1x`_f<_8Nr2VP7#((-Z8zqwP~J6o(wE05-|}
zIF#?Pcmc7EJNzsitLJ8S%57{|yb*1+IW-1%Q-G@pzahlxv)gfhf7tu`!{pETRjzS9
zhp8VZz1k2J_t>=0-Fh$b{V2ettTZsWrQsklV_|kwo?oMnKMI^>Rg`VyX-3hl&$>yR
zGhYENWu@-qmWDPOwbjXgUaH4XijDrBuVib-in5J7%_zQdD}`8JRsk%f(GuvUwj$7F
z9L1p|p_wJaxX;hhX=O2SYUf!G$19(9n>c8$0$4<`jea0c9d;3zoX_LXzS8@)r+w-m
z8KQfZv=YfU?Lu+TL<~1WUob16$Q9_^}3TM4)4LCWZdZZibiv$>&iB=@f&-ZzcU
zeH5VD*^Qbz>&%KArkpfIH5yHSQ1N^$HF9fhqIXQjL05@wrz^mPGYd`5I9!)Q$qW-s
zcDvo@Ds9TzPR1Qxxar)B#BRqZfQ7UB0X>U$FNz2Lc`2n*OjjoD3r`c=O;IBs-#&EN
zX}5@t4pV?jW)_;9^C2~Vb9f$yDV029nQ6EFPW4Sq+ounO<4t#_AK@n`fc0wjBsstS
z{%`1TvI!nJoXw#ekLjY_$AhObL;UomQ9lB&CblQv@VQC>E>^v)sXfU5bw>`Tp@?E(
z0df91n@SZZVu_Zr3zah4Cil-d{9Eqd^ynGG3*JM`CcjUbne`%Fz7Jh+spgAhQ~@rN
z386FQRe-D0`4~!gf>8d+TlM_Uf|uaXei-F?x8SXoB$elV
zo%pPw0F|azL7b-$847{v7cJ>q=P?%I(0CZ-hN#8uY^u=vI`O$$0V;~KsVFKDnEpvi
z9{kj2Ee=y!bRQi$m0HtHZ;_0vn=sDLzDBmbkxF0XpKs>ys)zB15Jx@6P|vFvG+d=X
zp%#w1=TXR^*yx~doyS=5J;c26Vq}lOkVnzBX_&iBnaR((su7=jE>*!(y)zA+^}zyl2B+pYlOhbmRli%*A(>FApq2D3j>#$3u-GsVrj0P{QNIbYJ3k2;hz-%~8vN{}o5;!}Kon}3_{rTG(27aktc
z&iOw6f^~W32g%H%z&P`=x!V3><*`KqbrSulyK2K5b4XXh%iA^u=EFSPU$ZXH!a-;D
z=3~w(=@wbI!K0(q2r8;=JLK3
z-Up%VP{dCs=}^1Ve)`tq^h_UC(_K7&nbnidlHnOm`t4`rs=kHosbg^m<*jB=ln0-0
zdk;N#_WQ7)Jtf>|0M0XH)^IT^jB$N{v05r_-A)7aaaJG-5Rm<52pe_8INNN5>V#
z?1HdX5#r4lVh%=+rKRA|;!rd~HO20&Wv@RSmxhl12O7aHZ>!0y-SiR-<$uG@7K@
z4!D)rgr5$p3+fR@Qh)_L@kz8BB_&pB*RPr*{b{HY4I8v!8rqCGS83-WP{E=1Jrwy+
z(BXRT3B&}7_E(VymnmLWC-+FIvAP=?PSR{Q+%VZWioxNXIJBEa>kSQjZ&PnnGgOd0
zMs0JOuC7%&A~@`zt{~P{&ONoC6}!!-FuEy-g_~@rrUzeD*UMF}e>yif>;sSVk|EX)>$-@I>G|z5$@FI>p2w-0r{N?@+%R@5iux+v!)`3G
z28TAv&K9IRox|gRbS8jqI~6d(@f5NBEG172_s3$C*ofk0fD2(83ZS4yu~%5aRPSOR
zs#{S6KT8uiluWe8K9){}(Nq9yd1%udu{kEch<(I0i+k4Ydk%+k3MHVO799RoE&K+n
zdBwk5Q|vS6B;|kM(3$Wox7tnja438F!zlr6x!`bwLy?aKy&H^(k4RWfP2!CJ;cD2$vYWstT4J1
zU^TzuJsj)u#iOWFY4~pa?Z<{EU&ZKr)tJFRu~XLthrhehF
zr?|8y9AksSaRQ6AT>M#hRC?IxXlvobz0-Y@dI+3Yg50i^
zl01vB8Iya$F*cBlf=)5H3)yY9|8>I(o*t8H;C?gPBAbz+)H3y
zOVM|c2L0AFu!C*eCNQrZ0+!o)7B1;zGH}VZF)%os!=dQ7ku|=WPE`Q4_1GT#)Q2{#
z!Gmt(V=R#;4lyb?JcL7$_*>tiGw+3+>a>+Ezd<`ADrln{&Wmj88>;<<-56}z?x&SOY$7#vRfd4Y{}s6EVEEfBLsRM574a8+y!tl1b69M0rW)I@Q`UhRz<
z&WG-G=CB6O#Cg1q2OIIv-Efnl1BQ@uaQIamQgv@MoCwvxRwNVxgEqS1yxQm>w$A4U
zc?O5aawu{SKS8~LRN6I%1CX2(f^y~9q?x7{NiYJ{`rK
z`9Ce3>V^2J?eVEOQ>+eA=iqSidnn?n&}t0-#?K$9XC(t`9JZ|hNvAlG;dIj|@~0uC
z6dcayP$Xv2kAD*R#6O4Ji@N7)hNzx`LKrh2W5+3l5L!*Ny1G;o3hJuvlUj
zp^`~-tN9e?F)-P|;ZfkRvRm!_-!R8Kx2MIA*X}B#fJK&wL-DV<)#mXC?iL!yaH0aJ
zyVzrZIivWjwcnqKBG1|i1@wR<{x!GSJRU)5#}Cf#ADpD1F+|;y?SyK~4UaRjilw3g
zs9p^unMXIV4bOZDV=0H=@IVelYm{E>F~FQrd{#V(JqnO|IYnuP++xGKp#(jwPy}>@mzdQFs$1iLdgV&hjS>3a}5srYYaSyDjmb70;rzYIZHT0&Rza_Cc)ta97@eRkK2F`
zHb-9Un6VW=^}4viKx9>IbPzjFqcD{_#ms&Ms1omD9PldADf`oY)DEPc3>BoBk%!=n
zM&YE`xvGV!+$mI~V1+87fk6c%0P3
zJ5!Ae0(FT(>|rsn;P6TgrC`%hq$VgYyQHSSK25v2>6ER2~`5eHCf{gKqJ~+me7fRMKoi{gdGlD&E5j
z-a{!2l}d)kq3G#@@W~a(Yos&5;WgOgMcO~3MNLLj7tXuHZ&W_70s_2o4wGP-;B!Riut_Hbl4;6(BMF!{ToFWN>&Thfo%7nq%zy%e<-aJUeM
zN1%utzTenYznDEdu_(-192QZW_#_63YXTn}F2`YN6ne+r{EYtFHni26jrj1ag2P2Q
zl)fZ>hEb$_9^Ub5UOzaz6NiD~niTENDmYx1!&F^*&8DEZzi(oPxe5e_t8*yz&QVM=
zUB6?bP3E>y?6y;Z;4nD6fdV_beEsm?@HSmY4;l`g4n<;yRoMhj-<$
zN#h%{(!YX(D6Z3p56>hxyf=r^zQ|Q>=P07j!@GZ->j#Io=P)%B(v{mtBdxB}i%-rZ
zIQ$Y0wTTI{d?-xPM`OddN`c_;+c=a?BFvh@tC}y)RRw~>FXS*)w~3!RXg7p$l>))x
z*K(*WrMwx2I)`zI0>R<;bC?>-fKZk$X}&mA6^H^ng+ncQG6+jrjp4}(1cwjh@Z>&=
z<7@?j!{9I!xL$$a@cJ6qKPhAN2?_*enCw1i=e@
z6)C;fum9(t|NDRc_UrxmZ~D)F(trNzAHRP62mR+CzyAI0{`Ie)=iiH;zkGfD_Ft}m
zE3j69Uu%!|(_H~qfD~{J{p)}$uwDV@aD5N_h2RP}ht8oZuwDV@aD5N_ZQu$xhl@Fs
ze|Al_PvkQd@W$`Op=0SBE}qDTHUP+rEuX2(qi*f*!}ULXV(7(vj~dNKUDi1~iNiqW
zqXzULmvs)eeL#FdN*K`iob4b%B86%reiTa}Lkokbum8o-nL8zN2%vBZq_>zX`RG0rJL^dhe?_hr4h{a|VEE0;LCn
z`Mmd&}E7ho^EFn3VWQ`=kU%PhIgjZxIg61;f@^A
z+yFe6-$FA1kSZ+qAI(Qq=p1g!A)uJS%<{-l+?;CX@DUsaRyB>APv>*Wa}LkokPx!G
z_by`q#pewA<~MZ?_vMgAM`Clym?c0a4EE*&`jGOh$`p4bYu4dQKN;ZT%p!g)w6cWTxfX
zn?C$>tNOZaMV^PN+;V-;*@&4X3^V(;({&0|a`^iC;$P6t)Ust3AHG*gY5~k1BQulz
zaGe)k-y}VBiwTSx5G01GXP3*21z;z^=bb4Cvw!>;CX?q0Xz0
zj&KP5uq-nK@*~Kz>cWSfi|UQ%kWM^Qs}swPXbmk-fs_j4crYN|+gv&>AYk41&-^Yp
z!h2NOqw4qq4kcH*VZkF~v<ZkIEU_VyvnHRs{P_raGx@YpKwjqAz
zJ@0Xr6tJ4K%Z>6BvhN|?=C?qVp$D2J@IX8*Apn*#esgIyEbl|T0l!5Ih{{ufy`dC0
zD=EhzAe31`=j@R;Q*-onKOmND`(sDiiL%oR{(z!1FI0aB#+2#yO(MNJG+0hts%CK=4
zyK82t9@#D5JTLd+S^jtShbiD3{yvLXWMkwj(Z8Ken~fZYq2;O9TGTJ6BpLwkLyDhv
z)q5Ny6@IHXm_tDE9vW_V3&a50ESD*+q+iC9Egwl+hHWUy&Lv6d$ezsM`@~`2&7PbY
zWra4wQnD1ajqwon@QQaLV1OS
z_8boV+i7$LdO719GA&@}X@h{Ulwr{Ta>|%qm+78I7P+mxibE2lyWo#a_#-6@SqdKD
zhjv9HWwvO5&a<`wvf#7qX%L2kK%BK*yVL2#9BPC#Y0xbl5Iiz$f~NAg$@XMg#vKQ`
zP3YP~j)-uW!bbX`AM%lAOh45z-Q|V~$1TSV{hpaY$?lDNX2N@N2(!|6xhEdessb^e
ziB0!gS8_-%H0TGs^yE``#7h~|crlr(+MYJbrynF0Zfu-y4+_+C2q-dL!H}(jN4%6V
zWLLBVGFXZ>1
zYl86vUNH#-1&3oitvgwlG3Cpvl^HJ48zXpxz?b9B>;iJa-xXU_+
zU4BOVaHwBI`S+N7Dmx+lMq6&z_QJW;#q{+oyjsVjL6a^+`M@NdIi#)_@#8RPBriM8
ziX|1FyWFr;yHyM*_CSi-uiSw{B1(3G0W%tMue7I)nmlw9d)nQ59VB&YAIb-2NODNZ
z8bKPtVXyg!=8;2liXFYkK29m)11W01@?Q=qmsFGNB^-{MEx4U!`8DigIbFw$6Q?mV
zl-fR*Ps{MZA)q*#Luei?8>b<&U7wZl45KfSI8#REQRb$r9?5E-Mp65Ha~zVgMijXR
zrSZHm7~N+G@~4&&KGwNXMMnMI6{}7N<+YFIqcZg5un|IPWc3ipjW7_YKAq3W
z5D^R1EMhDl44HY^*#5Acv!#qZfa*|1>Vm=FMa=3XvbN_?)PB=z4oTTOUB;)fLu^;~
zTW;iRQKQ4)ZRA-u
zR2%KuR%C!O+Fuk8$q?tTJBrYru&ija+!D=6&Yoj_NUoF=Z#BmM9|pq_vY3ZZ)PBtw
z9LmP94b3ZBauRJE0?w#1wIIP$ByVFd)X+YoPsotukS-5`zP`TdenB2uwscx&W6!AR
zJ}NJ(0Y;1FMSJmF^Y4+Kz+38$!#RYmgk@1*IXIe%oJV0Yqu7*CZ>^?$O@#td!{>fh
zU@V8wkFcy8g?OqNQ+@CmanYuu$kXOVN`V}Qv
zqiYUHBM|fwMTif}mKOeGxDOP|ZlYUL)R)p=IL>)XDbSxoke-+J7V;KpESuar9xR0o
zw!J&0k#JUO5L15G&dXH%q5er6+MCBhvvEfd*58TcWy9X1qDaoq#w98od1+jxIwiow
zAzel)^2+`eQAP&a-nPiz^%Hx~3bfSZv3IH{QlABQ=zuy8q&;X^!y##uLNO|zy=Sof
zo&@Z4D-fKP_GT4DMh^P?;jRN(JO>dNO0{xG(NY&XhsJKn8L=Y1#{nu
z#!*Ry>H4K-e;O+}q)Wa&|FlM4o9&cp;OF>YbQ~{FWmEuKKuhRRucbby<5|(wvKw#UUJCwo0jR`rO{Ler(e%-ikDwsn0?hJ8-CPmFF-L
zf6p;K{#KDrZGxhdwzedFyWm+uV;P53qOAV){kQU^hwMCr`lpeU)a~6AC~fX#_nQJN
z>Xcv!x8vn}6lZhDR}F?mSdUq&fNWV4MJ0rM9MpLKt8?WA*`ADI6Ng;1G(Hqm639rh
z8x{8L6BNLfsh;LL-ukrH4YOs#9eFv8#+4lQQrPnhRe*<*jaIa>NPHykd$Fr?`GRch
z%OO?9RchlyM0IV5?<=xr8>av^PIWfl_sXY(?vpJZZc58JDApXKYh_PHagJeQkj|cV
zgaX{PU}PHI=h28eaLz&$>B^&NtT_N$BA1yS$guB=u_|sHpa8ZnJIa|cus)g~N%{(K
z+3#`vJru98M6~kLa#|oK7oF=~>TZ=w5m%VY)nd*yFL*K%!XzLqwj_$(LjE*?E7ZZ3+0~6hSv1)44i-&3W^)B(Lr2?_
zq`2acMjAdDs45;ghm#t8r(<9uM=vKycZDKcvjVov7UytMmv3+k3}W5#_4%)#hGi<}
z4E65KAt*aTP(P!e0?L$*dgje6vkq&Kn#s^lqaL{>X%FTw6qcgV--pS*JmEofYNhkFf;~7?)Y~xOb`ovLjLZHGsg7GkP33FHeMxtQYuGOO8((b2+3s
zfhkYL8V!)PfIcY;!SaN`KSkcANTUtr(7DtIiv$*5g+P^dw#^^
zwDD)d6_CA1*{_j6)*TAF-jnv{1COH1Ke6h+#gwL|H|md`l6OXFjiZeL$ucqaV^;O@w(l>$lhzjo7SOI8XYWeETBpeh~2x6kk
z=tgv=r&kYl^c3x+BeXMkG*-nNCR3+x0$Wf5UvIAfbTG4gb)r!pkrGKqN>6GR`qR@}
z%^{URr^sU1b`DX0Ul%FBlXPjk8i0%@FRHURcnpVhk${}O5ujN1KGf;hqkn8j4~GS#
zSSH`FjRMe0%kpJrGMa71)y*76E6h8iD30QgN|E4!4Ta87*3THA0Q9kR`N{&B$~NF0
zD&=?%2|RhhH5?L_@}p#M#~BL9CX${1X$!%ye0?(sPQ9F@%SaCCQcRt^AUofP%EhHE
zvye?vf(IHSml!!oU_Yjt0?c)on>+v){(`_BN`#y2wz$wwXQwxqIM1QY-+Y=BXCH61^=b`
zGJdA!epa0VvR`Ch_O~^luF8sCRS>=vxZ74;%~^7_DRN9sOMWIDFAJ!4y$N|2BxFAr
z)?;M4mx7QyG9cI%tzlQ4;J&M`0@#$QfwpwNI3{z?9!0{%X$iDcEFotqgXtv5^@?#w
zP6)H8j9W57`=eP3U{iXGxMdg?#=wnLxB&+4Um&JA|FSni6{~ZyydXA=DhciL!N+YYoO`gL?CFP<&g<
zjGf&o3~tKH6d_&wm#37y4=o&aM3Jh$`S@>eJsuG@w!)@kF?>NVx{#Jn!Y8J}E;!`<
z!7y^DQM9WGCvGsPH!lGMr=`7FMUnELqK#dG<>_Fj*y!lz6H_^J9P;L1*df#$QU;@%
zaOiuZe}*X#QG3icQhkv07-yp*Or8RE3W*VZK01|r6o-9Lq-zWt#fK*5$zY>m%8gt2
z2#aCNnF+f*B?ZGce<&%Fe@6~UV*Pn2F2k-JQFzRoFxpLhdeoDFE&3>$1e_Td#ytu(
zWb!9Dgz8_3e}*RSha|L&$`^G;_6{4$rzMVPI}1XZMSc1lPX>e0kHQ5rr;az?g44Vr%U)nbw-rF^?zAEyUV$8`7TLpSuqIRq{8q~)JNs<5>8IKI8#Xg(@a
zT+CT-LOMMIK(w}YXXeDM9z~?lm(P=S`BWz)kE1yAM?ka%MP0D>D@5uOOXpr^uy{&O
z*(Cm&!%NI80Z|2uS{u(WbC!=iD=yuz*C4f3e>NHSZOfR%A+f4^LmoSd@$JX5F|F{p
zZVq9;e|EGB+sGlbjri&K3zCPW9mVJmT1ql)rq4R4UG1XQa4?+PWlV3Mq?JP{`X#Y4
z7;NsM#eltGc@`u?tBvYIPK&mUF>v(l`RR4R9EX=&Q2^+Exdr0o(mnxlm$Zit_bJJx
zAYj`Su8zbLH~ae63!CnFJ~#vsFQKA<_AN3)QTydaX`cd2_d2Br(k@c9I#`|h%@eyEau+847%O!98!Zzr$^2N*wxd&
z$ws&iEK7yz6^~_QlQb3Umn1b?YA
z-Q#6>#{sZO!P{||r;%D-I!1CzQuc00rs~xGQZ>5ALrI&A^>JmK$00SobeLdPqRUNC
zjMf%)mWnVa9%?%dfK3YS$>FQy3oQj(S_m<6Svpv9@1;Er%gah2p!C+G<7Ii9%=C$6
zyg8Iol5NMSdSf_3ZqH~Z!?ay7XF7?|(*mdQh*Vg`H79I=YBNprM|lO1Lpy{NDcexA
zF$Bx)`6}tD4AyqV%;_W*p0C8GB2{Kf#qH*7ftoLy=m9AOj^Qv|02&X=>fwVtYnRox
zn7>g9m6|a3TNF5qLko>G9E}qx$7_P!SnaCqpp0eOJSL^UksMlRY@be;v+m3G3fE?k
zf~3aF{YC}qIh1W6TmSx02I!~ckpaeXqhT_Sw#N;tJ_|hKj$WP_Z|eUHO`8Ih96}o|
zF{5}LBa=h{D{{(gDSP?&-lhOhxTsSetQEKqhjcd>j@0rtFf6+k<9(=d@C*
zRlU2}xh4*!?rZ~EddZPwz*G5%?B$w5J$1{S$?030)Mt6`?oq%6hf;BA16R>yCSE=w
zdp9Yeylt0#=`v;mHFoRWq4h*K1fgLWMNT{OyX4a&gp&ntWgFq?6$W=dqIX9WS;nE}
zE#;97gBbaU>?362BBA)T%U*QZ^T2&s7B?Cd_=^EZte1dOekr#@q|vU|~G%mb&t3uya?n|(Vg@K;K$GVo(u
zLLR+K25=p2SQL=bk!|FsR~Vk|5cX5xFNa|cq}CcCi$`W4TW^s8mf`alR^UUrrT_AL
zF3F893UuaB4$38j6wu`k&q*TX?e&&3=8;ExQud+*z+)lQRhk)+)xpzXT
zo{^tkVIN2L`#yH>e%Wu=lSA1mvNeR{kumlvJ(3iV(vjT@FiRdh+Bxj4KsOGdRhJOH
zC#m;kZk!P0wZPLW29EZ|jTke8L5dz_Ddm(K$&Q9W%!vEkH780p@egV6X#eRsK!FY%
zLZ4_Eg^-*Oc~@pe+zX|f#UY+MU<60VbzIIS4xve5nSu~FJWi>#1%uSRzH{dD;GquT
zFa_pu=uK@Q8P%KeKEy+ZO<{{N_t=}`klLVMZqOUK)WOmtBk!Tzv|C8&$j-mSdOgKM
z9m0_cAcr(t&;a97A_un4Fl~bGagY?S7iRf9@+=sh)4`Quq**QSn3QrE3#p2
zQouYvU7pJ0g1w<8H!G=?LqJY1y{YXJBQ@+oS|*7+%OPy{tUM9clfxl@HExuHoKJoZ2&FYhGT%)79F!D#0#
zl>rYL`DgSq1w7@f4je)Y_3{)gHmnoGOi|S6$5R}_=?c_v2yM$RHyrMRN|M?(!j{@D
zj|lcb`rM{e6NhwL-K|T{Z8TbS5l}b7FlWN}d
zM#$_CO4(Q0&f)J>(&x{Wv}l&9Ju)rZ`AYoh1O=SK9XVt|f>BK!Y=pEw$*2Dr{e-bT
z?g;1bDI97Dj~mt-7wjDF&LO=E3n+ovc7RVNsCr;|UYjzH|
z=1>w|$4jRe_mg*dC#3AtG5IzS;=kQh>
z0?A?doM}Gyrq1C_ICKKfg^((D4tL=YK(c=+g^j#CdM=+SYLF{u<28^oft0!;Ls}2v0<)OU=&V
zz8ps1f&M1!GWWYBaSm5<2&BpPAw1&cZUf}?bWy-LT*e`z6%2+D{Bqf)<(_0i1)Rf;
zIF!hNz2WG1NgWk%4tL=Yz~g1dW_zk_6>tvMaLAbDjcw<~3+t@{AO)Pm^&Adrt*1Rm0q1Zw
zhcq1FtLZ^g;-!vOz&TvN;pnD%{^JyI4xK|+V7&s);rbpN_ru!@?yi7y=p4EN>lJVg
j*Y}|N4_8lkoC40FbLa}JSHL-3--F|RczeO!75Mf4KF!26
literal 0
HcmV?d00001
diff --git a/lib/include/BitmapPlusPlus.hpp b/lib/include/BitmapPlusPlus.hpp
index fe1336c..fc1b662 100644
--- a/lib/include/BitmapPlusPlus.hpp
+++ b/lib/include/BitmapPlusPlus.hpp
@@ -466,6 +466,70 @@ namespace bmp {
m_pixels[IX(x, y)] = color;
}
+
+ /**
+ * Vertically flips the bitmap and returns the flipped version
+ *
+ */
+ Bitmap flip_v() {
+ Bitmap finished(m_width, m_height);
+ for (std::int32_t x = 0; x < m_width; ++x) {
+ for (std::int32_t y = 0; y < m_height; ++y) {
+ // Calculate the reverse y-index
+ finished.m_pixels[IX(x, y)] = m_pixels[IX(x, m_height - 1 - y)];
+ }
+ }
+ return finished;
+ }
+
+ /**
+ * Horizontally flips the bitmap and returns the flipped version
+ *
+ */
+ Bitmap flip_h() {
+ Bitmap finished(m_width, m_height);
+ for (std::int32_t y = 0; y < m_height; ++y) {
+ for (std::int32_t x = 0; x < m_width; ++x) {
+ // Calculate the reverse x-index
+ finished.m_pixels[IX(x, y)] = m_pixels[IX(m_width - 1 - x, y)];
+ }
+ }
+ return finished;
+ }
+
+ /**
+ * Rotates the bitmap to the right and returns the rotated version
+ *
+ */
+ Bitmap rotate_90_left() {
+ Bitmap finished(m_height, m_width); // Swap dimensions
+
+ for (std::int32_t y = 0; y < m_height; ++y) {
+ std::int32_t y_offset = y * m_width; // Precompute row start index
+ for (std::int32_t x = 0; x < m_width; ++x) {
+ // Original pixel at (x, y) moves to (y, m_width - 1 - x)
+ finished.m_pixels[(m_width - 1 - x) * m_height + y] = m_pixels[y_offset + x];
+ }
+ }
+
+ return finished;
+ }
+
+ /**
+ * Rotates the bitmap to the left and returns the rotated version
+ *
+ */
+ Bitmap rotate_90_right() {
+ Bitmap finished(m_height, m_width); // Swap dimensions
+ for (std::int32_t y = 0; y < m_height; ++y) {
+ std::int32_t y_offset = y * m_width; // Precompute row start index
+ for (std::int32_t x = 0; x < m_width; ++x) {
+ finished.m_pixels[x * m_height + (m_height - 1 - y)] = m_pixels[y_offset + x];
+ }
+ }
+
+ return finished;
+ }
/**
* Saves Bitmap pixels into a file
* @throws bmp::Exception on error
@@ -584,7 +648,12 @@ namespace bmp {
[[nodiscard]] constexpr std::size_t IX(const std::int32_t x, const std::int32_t y) const noexcept {
return static_cast(x) + static_cast(m_width) * static_cast(y);
}
-
+ /**
+ * Converts 2D x,y coords into 1D index, with changed width
+ */
+ [[nodiscard]] constexpr std::size_t IX(const std::int32_t x, const std::int32_t y, const std::int32_t width) const noexcept {
+ return static_cast(x) + static_cast(m_width) * static_cast(y);
+ }
/**
* Returns true if x,y coords are within boundaries
*/
From d271de10ae99c6a7dd4d65839949e880902355f0 Mon Sep 17 00:00:00 2001
From: Ali Ozer Tekin <74454719+aliozertekin@users.noreply.github.com>
Date: Fri, 31 Jan 2025 03:16:59 +0300
Subject: [PATCH 2/2] README.md
---
README.md | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index bb1bdda..64bee5c 100644
--- a/README.md
+++ b/README.md
@@ -249,26 +249,26 @@ int main(void) {
bmp::Bitmap image;
// Load the original bitmap
- image.load("penguin.bmp");
+ image.load(std::filesystem::path(ROOT_DIR) / "images" / "penguin.bmp");
// Test vertical flip
bmp::Bitmap flipped_v = image.flip_v();
- flipped_v.save("rotated/penguin_flipped_v.bmp");
+ flipped_v.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_flipped_v.bmp");
std::cout << "Vertical flip saved as penguin_flipped_v.bmp" << std::endl;
// Test horizontal flip
bmp::Bitmap flipped_h = image.flip_h();
- flipped_h.save("rotated/penguin_flipped_h.bmp");
+ flipped_h.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_flipped_h.bmp");
std::cout << "Horizontal flip saved as penguin_flipped_h.bmp" << std::endl;
// Test rotate 90 degrees to the right
bmp::Bitmap rotated_right = image.rotate_90_right();
- rotated_right.save("rotated/penguin_rotated_right.bmp");
+ rotated_right.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_rotated_right.bmp");
std::cout << "Rotated 90 degrees right saved as penguin_rotated_right.bmp" << std::endl;
// Test rotate 90 degrees to the left
bmp::Bitmap rotated_left = image.rotate_90_left();
- rotated_left.save("rotated/penguin_rotated_left.bmp");
+ rotated_left.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_rotated_left.bmp");
std::cout << "Rotated 90 degrees left saved as penguin_rotated_left.bmp" << std::endl;
return EXIT_SUCCESS;