+/*
+ * 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;
+}