--- /dev/null
+CFLAGS = -ansi -pedantic -pedantic-errors -Wall -g3 -O2 -D_ANSI_SOURCE_
+CFLAGS += -fno-common \
+ -Wall \
+ -Wdeclaration-after-statement \
+ -Wextra \
+ -Wformat=2 \
+ -Winit-self \
+ -Winline \
+ -Wpacked \
+ -Wp,-D_FORTIFY_SOURCE=2 \
+ -Wpointer-arith \
+ -Wlarger-than-65500 \
+ -Wmissing-declarations \
+ -Wmissing-format-attribute \
+ -Wmissing-noreturn \
+ -Wmissing-prototypes \
+ -Wnested-externs \
+ -Wold-style-definition \
+ -Wredundant-decls \
+ -Wsign-compare \
+ -Wstrict-aliasing=2 \
+ -Wstrict-prototypes \
+ -Wswitch-enum \
+ -Wundef \
+ -Wunreachable-code \
+ -Wunsafe-loop-optimizations \
+ -Wunused-but-set-variable \
+ -Wwrite-strings
+
+LDLIBS = -llept
+
+leptonica-projective-transform: leptonica-projective-transform.o
+
+clean:
+ rm -rf *~ *.o leptonica-projective-transform transformed_image.jpg
+
+test: leptonica-projective-transform
+ valgrind --leak-check=full --show-reachable=yes ./leptonica-projective-transform road.png
--- /dev/null
+/*
+ * leptonica-projective-transform - Example for pixProjectiveSampled()
+ *
+ * Copyright (C) 2013 Antonio Ospite <ospite@studenti.unina.it>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <leptonica/allheaders.h>
+
+#define WIDTH 800
+#define HEIGHT 480
+
+#define X_CORRECTION 200
+
+int main(int argc, char *argv[])
+{
+ int ret;
+ PIX *image;
+ BOX *viewport;
+ PIX *cropped_image;
+ PTA *src;
+ PTA *dst;
+ l_float32 *transform_coeffs;
+ PIX *transformed_image;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s <image>\n", argv[0]);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ image = pixRead(argv[1]);
+ if (image == NULL) {
+ fprintf(stderr, "Cannot load image\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ src = ptaCreate(4);
+ if (src == NULL) {
+ ret = -ENOMEM;
+ goto out_destroy_image;
+ }
+ ptaAddPt(src, 0, 0);
+ ptaAddPt(src, WIDTH, 0);
+ ptaAddPt(src, WIDTH, HEIGHT);
+ ptaAddPt(src, 0, HEIGHT);
+
+ dst = ptaCreate(4);
+ if (dst == NULL) {
+ ret = -ENOMEM;
+ goto out_destroy_pta_src;
+ }
+ ptaAddPt(dst, X_CORRECTION, 0);
+ ptaAddPt(dst, WIDTH - X_CORRECTION, 0);
+ ptaAddPt(dst, WIDTH, HEIGHT);
+ ptaAddPt(dst, 0, HEIGHT);
+
+ transform_coeffs = NULL;
+ ret = getProjectiveXformCoeffs(dst, src, &transform_coeffs);
+ if (ret != 0) {
+ ret = -ENOMEM;
+ goto out_destroy_pta_dst;
+ }
+
+ /* Transform only a part of the whole image */
+ viewport = boxCreateValid(0, 0, WIDTH, HEIGHT);
+ if (viewport == NULL) {
+ ret = -EINVAL;
+ goto out_free_transform_coeffs;
+ }
+ cropped_image = pixClipRectangle(image, viewport, NULL);
+ if (cropped_image == NULL) {
+ ret = -EINVAL;
+ goto out_destroy_viewport;
+ }
+
+ /* Apply the perspective transformation */
+ transformed_image = pixProjectiveSampled(cropped_image, transform_coeffs, L_BRING_IN_BLACK);
+ if (transformed_image == NULL) {
+ fprintf(stderr, "Cannot create transformed image\n");
+ ret = -EINVAL;
+ goto out_free_cropped_image;
+ }
+
+ pixWrite("transformed_image.jpg", transformed_image, IFF_JFIF_JPEG);
+
+ ret = 0;
+
+ pixDestroy(&transformed_image);
+out_free_cropped_image:
+ pixDestroy(&cropped_image);
+out_destroy_viewport:
+ boxDestroy(&viewport);
+out_free_transform_coeffs:
+ FREE(transform_coeffs);
+out_destroy_pta_dst:
+ ptaDestroy(&dst);
+out_destroy_pta_src:
+ ptaDestroy(&src);
+out_destroy_image:
+ pixDestroy(&image);
+out:
+ return ret;
+}