From c0f53c5d429c4ce3d11606800b54fabcc5405fc6 Mon Sep 17 00:00:00 2001 From: Marco Schuster Date: Sat, 27 Jan 2024 15:47:27 +0100 Subject: [PATCH] add unit tests for LeptonicaFrameConverter#convert(Frame), see issue #1115 --- .../java/LeptonicaFrameConverterTest.java | 130 ++++++++++++++++++ .../LeptonicaFrameConverter/mat-bw-10x10.bmp | Bin 0 -> 1198 bytes .../LeptonicaFrameConverter/mat-bw-10x11.bmp | Bin 0 -> 1198 bytes .../LeptonicaFrameConverter/mat-bw-10x12.bmp | Bin 0 -> 1198 bytes .../LeptonicaFrameConverter/mat-bw-10x8.bmp | Bin 0 -> 1158 bytes .../LeptonicaFrameConverter/mat-bw-10x9.bmp | Bin 0 -> 1198 bytes .../LeptonicaFrameConverter/mat-rgb-10x10.bmp | Bin 0 -> 374 bytes .../LeptonicaFrameConverter/mat-rgb-10x11.bmp | Bin 0 -> 414 bytes .../LeptonicaFrameConverter/mat-rgb-10x12.bmp | Bin 0 -> 414 bytes .../LeptonicaFrameConverter/mat-rgb-10x8.bmp | Bin 0 -> 294 bytes .../LeptonicaFrameConverter/mat-rgb-10x9.bmp | Bin 0 -> 334 bytes .../LeptonicaFrameConverter/pix-bw-10x10.bmp | Bin 0 -> 1198 bytes .../LeptonicaFrameConverter/pix-bw-10x11.bmp | Bin 0 -> 1198 bytes .../LeptonicaFrameConverter/pix-bw-10x12.bmp | Bin 0 -> 1198 bytes .../LeptonicaFrameConverter/pix-bw-10x8.bmp | Bin 0 -> 1158 bytes .../LeptonicaFrameConverter/pix-bw-10x9.bmp | Bin 0 -> 1198 bytes .../LeptonicaFrameConverter/pix-rgb-10x10.bmp | Bin 0 -> 374 bytes .../LeptonicaFrameConverter/pix-rgb-10x11.bmp | Bin 0 -> 414 bytes .../LeptonicaFrameConverter/pix-rgb-10x12.bmp | Bin 0 -> 414 bytes .../LeptonicaFrameConverter/pix-rgb-10x8.bmp | Bin 0 -> 294 bytes .../LeptonicaFrameConverter/pix-rgb-10x9.bmp | Bin 0 -> 334 bytes 21 files changed, 130 insertions(+) create mode 100644 src/test/java/LeptonicaFrameConverterTest.java create mode 100644 src/test/resources/LeptonicaFrameConverter/mat-bw-10x10.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/mat-bw-10x11.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/mat-bw-10x12.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/mat-bw-10x8.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/mat-bw-10x9.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/mat-rgb-10x10.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/mat-rgb-10x11.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/mat-rgb-10x12.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/mat-rgb-10x8.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/mat-rgb-10x9.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/pix-bw-10x10.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/pix-bw-10x11.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/pix-bw-10x12.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/pix-bw-10x8.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/pix-bw-10x9.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/pix-rgb-10x10.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/pix-rgb-10x11.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/pix-rgb-10x12.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/pix-rgb-10x8.bmp create mode 100644 src/test/resources/LeptonicaFrameConverter/pix-rgb-10x9.bmp diff --git a/src/test/java/LeptonicaFrameConverterTest.java b/src/test/java/LeptonicaFrameConverterTest.java new file mode 100644 index 00000000..d888d0b4 --- /dev/null +++ b/src/test/java/LeptonicaFrameConverterTest.java @@ -0,0 +1,130 @@ +import org.bytedeco.javacv.Frame; +import org.bytedeco.javacv.LeptonicaFrameConverter; +import org.bytedeco.javacv.OpenCVFrameConverter; +import org.bytedeco.leptonica.PIX; +import org.bytedeco.leptonica.global.leptonica; +import org.bytedeco.opencv.global.opencv_imgcodecs; +import org.bytedeco.opencv.opencv_core.Mat; +import org.bytedeco.opencv.opencv_core.Point; +import org.bytedeco.opencv.opencv_core.Scalar; +import org.junit.jupiter.api.function.Executable; +import org.junit.jupiter.api.io.CleanupMode; +import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.bytedeco.opencv.global.opencv_core.CV_8UC1; +import static org.bytedeco.opencv.global.opencv_core.CV_8UC3; +import static org.bytedeco.opencv.global.opencv_imgproc.line; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +/** + * These tests compare that the Frame to Leptonica PIX converter works correctly against known-good + * files that come in different stride lengths. + * + * @link Source bug + */ +public class LeptonicaFrameConverterTest { + @TempDir + static Path tempDir; + + @ParameterizedTest + @ValueSource(ints = {8, 9, 10, 11, 12}) + public void testBw(final int cols) { + LeptonicaFrameConverter lfcFixed = new LeptonicaFrameConverter(); + OpenCVFrameConverter.ToMat matConverter = new OpenCVFrameConverter.ToMat(); + + final int rows = 10; + + Mat originalImage = new Mat(rows, cols, CV_8UC1); + int stepX = 255 / cols; + int stepY = 255 / rows; + int stepTotal = Math.min(stepX, stepY); + for (int i = 0; i < originalImage.rows(); i++) { + for (int j = 0; j < originalImage.cols(); j++) { + line(originalImage, new Point(j, i), new Point(j, i), new Scalar(stepTotal * j)); + } + } + + //System.out.println(String.format("orig\n capacity %d\n w %d\n h %d\n ch %d\n dpt %d\n str %d", originalImage.asByteBuffer().capacity(), originalImage.cols(), originalImage.rows(), originalImage.channels(), originalImage.depth(), originalImage.step())); + opencv_imgcodecs.imwrite(tempDir + "/mat-bw-" + rows + "x" + cols + ".bmp", originalImage); + assertDoesNotThrow(new Executable() { + @Override + public void execute() throws Throwable { + assertArrayEquals( + Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("LeptonicaFrameConverter/mat-bw-" + rows + "x" + cols + ".bmp").getPath())), + Files.readAllBytes(Paths.get(tempDir + "/mat-bw-" + rows + "x" + cols + ".bmp")), + "Mat file differs"); + } + }); + + Frame ocrFrame = matConverter.convert(originalImage); + //System.out.println(String.format("frame\n capacity %d\n w %d\n h %d\n ch %d\n dpt %d\n str %d", ocrFrame.image[0].capacity(), ocrFrame.imageWidth, ocrFrame.imageHeight, ocrFrame.imageChannels, ocrFrame.imageDepth, ocrFrame.imageStride)); + + PIX converted = lfcFixed.convert(ocrFrame); + //System.out.println(String.format("fixconverted pix\n capacity %d\n w %d\n h %d\n ch %d\n dpt %d\n wpl %d", converted.createBuffer().capacity(), converted.w(), converted.h(), -1, converted.d(), converted.wpl())); + leptonica.pixWrite(tempDir + "/pix-bw-" + rows + "x" + cols + ".bmp", converted, leptonica.IFF_BMP); + assertDoesNotThrow(new Executable() { + @Override + public void execute() throws Throwable { + assertArrayEquals( + Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("LeptonicaFrameConverter/pix-bw-" + rows + "x" + cols + ".bmp").getPath())), + Files.readAllBytes(Paths.get(tempDir + "/pix-bw-" + rows + "x" + cols + ".bmp")), + "Pix file differs"); + } + }); + } + + @ParameterizedTest + @ValueSource(ints = {8, 9, 10, 11, 12}) + public void testRgb(final int cols) { + LeptonicaFrameConverter lfcFixed = new LeptonicaFrameConverter(); + OpenCVFrameConverter.ToMat matConverter = new OpenCVFrameConverter.ToMat(); + + final int rows = 10; + + Mat originalImage = new Mat(rows, cols, CV_8UC3); + int stepX = 255 / cols; + int stepY = 255 / rows; + for (int i = 0; i < originalImage.rows(); i++) { + for (int j = 0; j < originalImage.cols(); j++) { + // Warning: OpenCV uses BGR ordering under the hood! + // See https://learnopencv.com/why-does-opencv-use-bgr-color-format/ + line(originalImage, new Point(j, i), new Point(j, i), new Scalar(i * stepY, j * stepX, 0, 0)); + } + } + + //System.out.println(String.format("orig\n capacity %d\n w %d\n h %d\n ch %d\n dpt %d\n str %d", originalImage.asByteBuffer().capacity(), originalImage.cols(), originalImage.rows(), originalImage.channels(), originalImage.depth(), originalImage.step())); + opencv_imgcodecs.imwrite(tempDir + "/mat-rgb-" + rows + "x" + cols + ".bmp", originalImage); + assertDoesNotThrow(new Executable() { + @Override + public void execute() throws Throwable { + assertArrayEquals( + Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("LeptonicaFrameConverter/mat-rgb-" + rows + "x" + cols + ".bmp").getPath())), + Files.readAllBytes(Paths.get(tempDir + "/mat-rgb-" + rows + "x" + cols + ".bmp")), + "Mat file differs"); + } + }); + + Frame ocrFrame = matConverter.convert(originalImage); + //System.out.println(String.format("frame\n capacity %d\n w %d\n h %d\n ch %d\n dpt %d\n str %d", ocrFrame.image[0].capacity(), ocrFrame.imageWidth, ocrFrame.imageHeight, ocrFrame.imageChannels, ocrFrame.imageDepth, ocrFrame.imageStride)); + + PIX converted = lfcFixed.convert(ocrFrame); + //System.out.println(String.format("fixconverted pix\n capacity %d\n w %d\n h %d\n ch %d\n dpt %d\n wpl %d", converted.createBuffer().capacity(), converted.w(), converted.h(), -1, converted.d(), converted.wpl())); + leptonica.pixWrite(tempDir + "/pix-rgb-" + rows + "x" + cols + ".bmp", converted, leptonica.IFF_BMP); + assertDoesNotThrow(new Executable() { + @Override + public void execute() throws Throwable { + assertArrayEquals( + Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("LeptonicaFrameConverter/pix-rgb-" + rows + "x" + cols + ".bmp").getPath())), + Files.readAllBytes(Paths.get(tempDir + "/pix-rgb-" + rows + "x" + cols + ".bmp")), + "Pix file differs"); + } + }); + } +} diff --git a/src/test/resources/LeptonicaFrameConverter/mat-bw-10x10.bmp b/src/test/resources/LeptonicaFrameConverter/mat-bw-10x10.bmp new file mode 100644 index 0000000000000000000000000000000000000000..06e89a843490e82e16a5d79b5a48d11a5befdd22 GIT binary patch literal 1198 zcmchXXEYEB0EIs#A<-bClD3&qlq6DVhzdzX*_G8oRHBHCl#!NEk+f(N+S#Km4NBWA zN)+lj@4dh8@4M&Rd%tt;|7&ELA;{m->1o9t68+Z#2>&zuM+yiC(5qK3diU;)pr9aq z`t(6aNQl0D`ywnXjEIN`qN1Yo>(>u4F){l0?~k~+I1&;P3>YwgfddCJXwV=A4<3x9 zq$E;OQVba~1Zin$WMpKJm6b(KPL82Nhcax~Foq8wj=a1)BSwrsK|z6$BS$i7)F?)e z9?h6BV;DPjEaS$FWBmB>C@LzVq@;whvN9?vDyXWeqNb+Cgb5Q+S64?vLjz4sO|-PM zm^g7FlO|0m_L6$CMG5+uU^fXHEUSAb}g>1uDH3m;qLB^hldBAo}R2* zw~qDe*Rx^61~zWo$fix3@bdD)+uIu-A0IYv-i)uWFMfW0Y}vAfty{OUZQC~d{r%a# zeLDdG0R#pHvSY^%cJACsP*4!T!NKg>wTqCD5JE#k*}Z!=VPRo}hldjp5kX{RBzyMk zAu1}0y?ghvZ{I$mqoaw5i6J&Nmbkb$_V3?Me0)3y4jka%!Gjz+bcn-;4|C+m5fTy- zNK8y5DJhBMJ<73T$2flcI4LP9q^72F;=~Ek($YA2@+9f$>6|)siqof0bLPw$ z&YnHXxpU{p$jBfwGn4b@&vW6z1ukB^$fZk{xP19CSFT*)>eZ`cWo40_oz1mt*T~7q zAvZUdyu3WFU%$?c8#lOl^Cq`$-QxD`+uXTxhr4(0a_`HZcl~q*stZ32@GK!)-(K1SuWTdDRX(BVL z?Ah`E`}@6f?tAw6FG{pjDnKN1oW3>YwgfddCJXwV=eB_)xPl0sTq zn!$qyBO@cjkRd}DI&>(*h7ChjR+izzhcjZt2u6+^$*57I7(IG4a&mHv88e2lW5*&d zFOPzP0^`PwWBmB>C@LzVq@;whvN97UOkm=~iAK@2S65e7u3U+mn;Y)#?s#~3uxiyRR)~&f@b>n`$Hxa>UtczE+{mU)o7lX0Gh4Q7Ve8hdY}>Yt?c2ArW5*75?%c_) zUAx%5dpCRb?7`2^4}X7u0s;cqyLT`9_U$7uFp!|2AcBK~2?+@yG&Gd3urT)T-_L;q z2M7-jCn6$($jC^dqM|r>@F3CA(HuH-h{J~ubL7YoVq#)Adh{sAjveFp@#CC0ae~;` zSmNU1IC=6Ur%s(BK0cm=gal5XKFygkXGly;Bq=G04GOl00PI-AbH*VaZqN0MEH*a$5)-7(| zzRjIGcc`qa_`U0uz+d-u41|2{P}HPqJDQdd{Ug9i_&udk<}p@D}FAM)tY zBN`hUdHnb>O-)TSH#gJL(n4!%D{XCUw70kOTOh?Cj+2+qb-X_m21P-}B+a2R?rMNLN=E-QC@M`t*s;OEbu{QC8a-@kwJ=g%LIQPH#W4v8iA#%FNut?y8r+H literal 0 HcmV?d00001 diff --git a/src/test/resources/LeptonicaFrameConverter/mat-bw-10x12.bmp b/src/test/resources/LeptonicaFrameConverter/mat-bw-10x12.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ac9810875e4fab1b7ef6ad39770440bd1a4c0f6c GIT binary patch literal 1198 zcmchLXH*Cb07Y*q4HczmNk$|)ZKH&UQcia6D67&C4br59N-`Tp0~rlTMiGj3 zG;G-&|G&TAJLkT4&oeg96yjfWdRD#1Bzh3*Qz|9_Q$fB?OE^+Hfk5FsHUgoTCa z-Mcp;A|i;2iXtW^hPb#mefso4LP7#bNlB!nr0CnXFa7%ULt0uI85tS+_wSFatSoYJ zats(SfPn)CA}=qGf`S5yii#*HDWR;a%%DMoP*G7~@ZiCys;V+%$Pk7O9m=p_!x%n% zIBIHYj2JP3kt0WB#*ZJ*gb5RvIB_DHnwm_S zGzl#&Ewr_@(b3UCS63H3Jw5dG^)WCoVDjY2Oqnu;sZ*yiZQ3*p4Gl3eGGhAl=@=Uu zGh@aKX3m_+tXZ=#F)?BG?AgqjGY3;sQ|8W{%e;B>Ff%j5+}xb`^XFq>VS%NkC015e zELgCBg$oyAZEcN>jSY(yEn@NF#VlE}gr!TDvTWHhmM>qq$C@>3Si5#D>(;Gf{rdIT+uP&d;J}6r8*p@VWaGw-Y}&Mm&6_u~Wy=m*>(;Go+qRAE+qdK6}JJ`8%C%(SE z`1$#0s{ltzkfeLK|uru2NMz!LTG3x2M!z{ zEG&$J2M==S&>_OZ!-EPDtP$tA(fStJbLtq$B!TLgwYC`}chK@PUsXKl16*Cq94v%$F};`1
    Chzxe(8H-G;80XYprYe(P6)V#{(|I_~hfc>_1 literal 0 HcmV?d00001 diff --git a/src/test/resources/LeptonicaFrameConverter/mat-bw-10x8.bmp b/src/test/resources/LeptonicaFrameConverter/mat-bw-10x8.bmp new file mode 100644 index 0000000000000000000000000000000000000000..07a89b971e1af05e54616899eae5639cc03feddc GIT binary patch literal 1158 zcmb`6XH*Cb07Y+Xn4 z>^(bve?Px>&VBct^YknN1o;=O9xL}Oksd^Q5cs$LUH@4E0s{2v)r;P}dm|_)h>(yF zefso4SXdYl5fS?K?Te_WDE<2NLrhGJ{{8ziV88&x#l?}3kU&yWl7RyUGHB2s1`i(0 zkRd~ml9FQR(4h<)HVkQLX=G$%7(RSBva+&_7%_s8BS#`9C&#E!qZmDUH1hKDC@3hP zsHljNk`iOajA889u_!AmGj7~C#*ZJ5ii!%Vs;a1|siCf}&V&gQm^g7FlO|0>CBihgPAjDGHcc>X3w6@oH=vQ z)6+v=UmpVl0}KrfF)}j3*w`2o6BA5LO))bw!`$4QxpU`YVPS!#r6pEYR?M3>kNNZG zV{L7Xjg1Wp7A(Nl)|Q0}7h-2;$D&1xu(!9z!NGyWix=bQ=*W^KOK@^>V(HSQEL*mW z<;$0|V#Nwpu3U+;vokI(F1Wh7;^yYYs#U9ScXwy?>eZ}Svjz_j57w?-i>Ie2>(;Gf z{rdHId3mv6!v;2P+=#cgH=8zX!pFyl&6_u~Wy=<}Zr#eZZQIzseLFjL?7-L8mz_Iz zvTN5acJJPepPwK8{{HOQvxmKV_p)!_J^}&)2n-A)C@6^F;9x>RLfF55KcS(a95`@* zg9i^178XW$csLOe5ky8ta_G<@4j(>DR8$nv(b2@j#1I=BOI%zWM~)mJK0cm=gai^3 z6G=)+A~`vkl#~>X9zDvjW5-BMO(iWYjpN6Ulb)W=i4!Nt$jBfwGn1^WEV8q+$;rtf zH#e7)Cr^@>m&d77r^wIG=k)2*6ciLtSXjuJGiNw^_AKYlo#XuZ^Ar^oQCwV1Nl6K% zrKMcBaDlS2GA>@c$fZk{C@(LkqN0M!moIbW$`!6&y~?#~*SLQDIyY|I;O5Pn+`4s( z%F0Trs;a22uBN7@hT7U%>gwvKudnC!?b|doG|<@C$elZPxO?|5O-)TSH#c+d-aT4c zTDX7zJ`Wx|ptZG?wzf7NK77cdM~`^?_%TnOJfXe4osNzUo<4obvuDqE{`@&FUcBJt z%a^=*^@`5UPP)3fc>Ve{-QC^1dGm(1Z{PCn-8xANct3BcDEf;`8UveEIT) ruV26N?b|oLfB(*pA3yl{^C!Q4{o?oU-~9RW2c$L3oqeP8{xAOpfIgdk literal 0 HcmV?d00001 diff --git a/src/test/resources/LeptonicaFrameConverter/mat-bw-10x9.bmp b/src/test/resources/LeptonicaFrameConverter/mat-bw-10x9.bmp new file mode 100644 index 0000000000000000000000000000000000000000..da21367b323eb3e55092161bc18be9c140e380e3 GIT binary patch literal 1198 zcmchXXFCuI0EJ(n&=AUKP!ifGN=2m*GE)jIGomdGG$<;CvKqFQ3Pp-SR5mH2th5(} z_IBOA->>&P&wI{!&JQ?xrl~^wl~zxx_B7ER#Ci}w7(RSB^78U1C@3&u#0W-?9EqZ$BBMr) zLP<%9(W6JBtgMWRiVCW#s*D*khOuMEGH%>B#*ZJ*gb5RvIB_DACQU+3O$~K*bu=_I zm^^thQ>IKoQ&STyEiI-_oyxRn)6mw|X8QE$%$PBQnKNgiqoaeat}e4?&0_ZK+02U2&n3%9&!2(Q8O))bw!`$2)3kwS@ zEiJLKvSQ)Fg;-l#vuM#G7B60mjg1XUmMmfE(xuqi+G1yChrPW$%a$!;`SRtgSh0eY zD_62=)hZku9B_1W#L3ACXJ=f*tl^cn>KA?^XAQXd3mvA%ND%7z1g~TE8DhhWBc~)?AWmbA0HoleSPus z^JC}Eo$T7Ri`~0-vuDp9{Qdn22nb;B-o5PGw~xTUK!SpT*uQ^22M!$I;K73g2M2TL z&>;>VK1@hR2%({&goTB1eMMtpFYi*GiNw^_AKYlog*bBh4bgn zbK$}TE?&GyYHBKJX=$XVr*rAjB`#mSOh!fqnVFefxpIZ9tSqixy~?#~*T~M!CMPF{ z>({Sy@PLO8AJWj! zKx1PgO-)TSH#gJL(!!%hk7#Xe~SdwV;OEbu{QC8a-@kwJ=g%LyySqV7!^FuqGOgs_bNCwSy2mtrnCo=3Ss69X7Cm4Q${f@bhJuh2r*xgZp{@K6u6V*00Tv zcRu)ho&Q$`Mi^y`aVD5#ifLvYy$G$e(M|`QbkR+puSF=OjB+Zdq>5_ld@e#NX{3`u zCRt>Y=VK8<2_u{cB8eiJIPZ(#iW}~D;E5OB_<36dQ_L{O0!ys0#?I>^sG^2C8fc=0 kHhNwbK@>5>kw6kDq>=L%duQA1OFPWYyDRP1`!VPL00bOab^rhX literal 0 HcmV?d00001 diff --git a/src/test/resources/LeptonicaFrameConverter/mat-rgb-10x11.bmp b/src/test/resources/LeptonicaFrameConverter/mat-rgb-10x11.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5ec5602510d14a1f40a5258dba47128263b30e01 GIT binary patch literal 414 zcmZwDp>YHt5QX9YY*GNBgD3UGB)Fy2F=hMEzlAz(<-ggCT-KMDNqc>Q354VGNn>FWl}cf8UZng zLjsbJj8vo}6WPc$5uzbFVjw1BCRSo6PU0qB$4>0VUi18s0S5sRWT?<#!iH=90mPDHd;kCd literal 0 HcmV?d00001 diff --git a/src/test/resources/LeptonicaFrameConverter/mat-rgb-10x12.bmp b/src/test/resources/LeptonicaFrameConverter/mat-rgb-10x12.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f3535727f03ea4e737c370a5feced1aee0ce882f GIT binary patch literal 414 zcmZvYp>04R6acTbsU_*#pg}%SOHxbf7y-i¨OR8pi~9G#j8;qd(QXTNWIaXjLR$*0EXHC{-T?P!p zunfltjKnC6%IJ*A*o;eqW@wh?Xn~e!g;r^uHffu7$&d}%k{vma6SVkLIsByQrxgEx4Kcldx$_=2zaj-U9AzbL3dE$YyKCbXax?dU`|dJzzV gSi~U#Nk~B|(vgX5oB#j- literal 0 HcmV?d00001 diff --git a/src/test/resources/LeptonicaFrameConverter/mat-rgb-10x8.bmp b/src/test/resources/LeptonicaFrameConverter/mat-rgb-10x8.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e6d49db5a74793a2dcd4269b37bcb101af81be81 GIT binary patch literal 294 zcmZwCp-liW06@`)BTPV59YI$hE3g+vsOuQ*8fQ90eJ8jTDsK}mXnyj)|KC3!FaG#? z`uX_!`1bhX{ptVQ+|ixg#ogS)z1-Wy6i|rSHH%3qZ literal 0 HcmV?d00001 diff --git a/src/test/resources/LeptonicaFrameConverter/mat-rgb-10x9.bmp b/src/test/resources/LeptonicaFrameConverter/mat-rgb-10x9.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f7643f18dd79e0c5d160a1f1bfcaa5c4b4de248a GIT binary patch literal 334 zcmZvRu~7ve6a@E&T7k?^fH8sdVpB#VN}vE5po14v0~t*aP{yYdPh)rXF4@no?+1T; z=-;&$?Nxj5rvIM{H*$?zxQ*-F$=%#192q&rDV)Y}&g5*4+LDoFtioz6XHC{-sSOz! z#wd)&aK>b8hFX`AZuCNLbf-`HrmIyMsYWf-Ms@0>ZmL?Ak!<8bZe%A<@+PY#8A(Pe jq(*YmByEyfkda`7LTCghOu{Cp{Sv{TKm&&f8=mk3nif!2 literal 0 HcmV?d00001 diff --git a/src/test/resources/LeptonicaFrameConverter/pix-bw-10x10.bmp b/src/test/resources/LeptonicaFrameConverter/pix-bw-10x10.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2dc2ddd2ce3a5ffd3da148d5a65d6560ca251df1 GIT binary patch literal 1198 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 CkhT8+ literal 0 HcmV?d00001 diff --git a/src/test/resources/LeptonicaFrameConverter/pix-bw-10x8.bmp b/src/test/resources/LeptonicaFrameConverter/pix-bw-10x8.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b6a6aed73172f067fec9514b51b4f73f4338c1ae GIT binary patch literal 1158 zcmb`6hc^%o0E8)(G>l3i6(S`KiH4RCNeE@6A__^G8nhHb$tILagN&AyRT&LLLZwZ} zsI*JtOWyBK_}zPV-`zWHBOf7wZfSH;xvL3xS)|K?-AzEir2G9Z1iO!a13^JSdi3Z) z&z?OI5)z_UuU_=--J3pr`XDSUOy9nJ5fKrgU%!6z@86#R0|qc~;6Ox0MG+GdLtI=O z2?+@X4I0GY!GjqxWC)Uyk_;U>lwre$Atfb+w6rubGBOMwJ{(zDSw@T)!N`##88vDY za&mIW%gdvnpup(Sqft~;L`g}BF=NJ{tgOt~v11uGZX7BqDvTdL9#vIUCQO*X#EBD` zG-(o(Cr?IAO^qp2rl78_&eW+>(a_L9Q&W>^)21I?c2xx{rmCu_U6EW0~|bf5FZ~Oe0_cK^Yi1-p+orl z`x6ilKww}XhYug-$dMxi1qE^R=uv`$g9!-g(u5k70RnpVb$;ikcGc%K{ ztSqv#v$=Nd8aX*R9p78YPQ=UD0#`EXTdGX=}FJHdo)vH(3*Vog~(7@~0uW4*- zq^YTi=H_PJym>=QOAD>7t+chZ(ca$9+qZ9d_wF6<-@m7$qk|70KJfA5M?QV}#OKeS z`SRrpU%!6k+qZ9g|NfmHKYq~J*~!nJKl%0R7r%f1=Fgu${F8u`nxTVNMB4wwzq`7c A-v9sr literal 0 HcmV?d00001 diff --git a/src/test/resources/LeptonicaFrameConverter/pix-bw-10x9.bmp b/src/test/resources/LeptonicaFrameConverter/pix-bw-10x9.bmp new file mode 100644 index 0000000000000000000000000000000000000000..666648e3ed24ae10db0ad3eb954e3d1b15f040c4 GIT binary patch literal 1198 zcmchX=T`^}7{#U1BpFSlgp!g{*)1Z;N~zFJW|_%|QX!#`jE33LQk0QZqEaDgkRl-s zQMTeIo%e5e?>YBAcYJ?LEK`MgbVI-Es&zTBE{bV=4i2%@5*h>3|IE-sFQgane3lJxG~n?8N|ASES5-@bj3mX@Yp zzkc-Z-=6^k1~72oKxAZOkd>81PEHPad3h8R6i`%DWYC~N3?4j~Aw!0sq@={qp+iwt zRz^idg<->np{lCN@ZrN5F=7NGM~*~IO$~K*bw-UEg@%R(qeqWMQ&STyEiJ~38H2XA zHe<(*MMp;mU0q$qjT?uao*w%8`WP4(Fn;`aCQO*X#EBD`G-(o(Cr@U|lqpP|Iu%1h zLyU}!Fg7;E#KZ(sQ&Xl*o5u9%(=jtMW5$db%$zwBb8~ZM&6gP z&6+iMdV1pJ<;B{yYgxB$9qZSxXTydKY}~k!O`A61?d{Fx&71M@@nOrBEo|Mom2KO$ zv3>h?e0_b{v1122ckaZ`&kuipe|GKKML<9Rfq{Vp1qHEt_ipy=*~8wwdkGE>X5YSj zgoK2!fB$|C95}$ig9ix>4J9lrj6;VGarp3IjvP5ccz8HRj~*o=B7$Sbj&c0>aZa2# z!O4>+iHwXSDk_TT=xAbMVmNi`6sJ$0=FFKhoIQJ%bLY-+{``4jV`GVniz7Zho`i%1 z5)%`-aNz<;Nl7FpCzFzrLTYL%X=!O(ym*oH^mH;ZGPrc<5|=MuCNndWtgI}qT)D#4 zt5>;p?HbpwUne^|n;SQ7aP#I(Zr!@Y?c2AxbLS2@IXUF!=5qJ$UGnnsxOeX!_wU~) zKR=&>f&vN)3wiM10Yybc6c-m$Qc}XhhYxx5=n;<}Kc=*_lqXM~P*zsP)2B}+5;*<_&M( zzUAG!cQiCK@c#XK8XFsFYHFgnxtW%h7CwCVKx=C&A3uKN)2C0gwYAaS-p=RGpZW6T z3tzu}<=eM!eEQAdGM#h$M<=Vu&S9q=Oso rc;JZ_-uU2)pLhc^%(1`{E3C1>7Q25*CQutq(lXjtC+TWEM!(|^T}NVp literal 0 HcmV?d00001 diff --git a/src/test/resources/LeptonicaFrameConverter/pix-rgb-10x11.bmp b/src/test/resources/LeptonicaFrameConverter/pix-rgb-10x11.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dc24a3fcb8fe584a2720c3831bedd6743406ea3e GIT binary patch literal 414 zcmXYnp=|{q6h+Us?EsVwst||{&;&)g0TNM3~(fsq)6(HNaE8H;fkV+e>r91@U(6r>>?naDy8B2u9ms-p&Kq84hScIu=q z>Y>(}AsezI2XZ18awB*0BrozI=Nus#q9X=kA{JsJcH$&1;vvT9!5h582YkX8e8YGA q#4r58dvC!StiuLu!WL}9cI?D1?7`Z50Rs*KBq-3J!-NIrZ~p~3YH<_* literal 0 HcmV?d00001 diff --git a/src/test/resources/LeptonicaFrameConverter/pix-rgb-10x12.bmp b/src/test/resources/LeptonicaFrameConverter/pix-rgb-10x12.bmp new file mode 100644 index 0000000000000000000000000000000000000000..357292f5574207403735a4c01d82a841ebf6b622 GIT binary patch literal 414 zcmXYtF=~V%7)0N;A*~Q^5G*aW71ByNk6;lGp_dRWx3=>H_FwG{th`2kesSt$60OiGtS5o34$#HI`QgsUz(A==Fi`M zAHMec^{Z3?_^J$3Ilm literal 0 HcmV?d00001