56#include <config_auto.h>
60#include "allheaders.h"
62extern l_float32 AlphaMaskBorderVals[2];
63static const l_float32 MinAngleToRotate = 0.001f;
64static const l_float32 Max1BppShearAngle = 0.06f;
65static const l_float32 LimitShearAngle = 0.35f;
110PIX *pix1, *pix2, *pix3, *pixd;
114 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
117 return (
PIX *)ERROR_PTR(
"invalid type", __func__, NULL);
119 return (
PIX *)ERROR_PTR(
"invalid incolor", __func__, NULL);
121 if (L_ABS(angle) < MinAngleToRotate)
122 return pixClone(pixs);
129 if (pixGetDepth(pixs) == 1) {
130 if (L_ABS(angle) > Max1BppShearAngle) {
132 L_INFO(
"1 bpp, large angle; rotate by sampling\n", __func__);
135 L_INFO(
"1 bpp; rotate by shear\n", __func__);
138 }
else if (L_ABS(angle) > LimitShearAngle && type ==
L_ROTATE_SHEAR) {
139 L_INFO(
"large angle; rotate by sampling\n", __func__);
144 cmap = pixGetColormap(pixs);
148 pix1 = pixClone(pixs);
149 cmap = pixGetColormap(pix1);
153 if (cmap && width == 0) {
155 pixcmapAddBlackOrWhite(cmap, 0, NULL);
157 pixcmapAddBlackOrWhite(cmap, 1, NULL);
165 d = pixGetDepth(pix2);
167 pix3 = pixConvertTo8(pix2, FALSE);
169 pix3 = pixClone(pix2);
172 pixGetDimensions(pix3, &w, &h, &d);
174 pixd = pixRotateShearCenter(pix3, angle, incolor);
183 fillval = 0xffffff00;
186 pixd = pixRotateAMGray(pix3, angle, fillval);
188 pixd = pixRotateAMColor(pix3, angle, fillval);
247l_int32 w, h, d, w1, h1, w2, h2, maxside, wnew, hnew, xoff, yoff, setcolor;
248l_float64 sina, cosa, fw, fh;
252 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
254 return (
PIX *)ERROR_PTR(
"invalid incolor", __func__, NULL);
255 if (L_ABS(angle) < MinAngleToRotate)
256 return pixClone(pixs);
259 pixGetDimensions(pixs, &w, &h, &d);
260 maxside = (l_int32)(sqrt((l_float64)(width * width) +
261 (l_float64)(height * height)) + 0.5);
262 if (w >= maxside && h >= maxside)
263 return pixClone(pixs);
272 w1 = (l_int32)(L_ABS(fw * cosa - fh * sina) + 0.5);
273 w2 = (l_int32)(L_ABS(-fw * cosa - fh * sina) + 0.5);
274 h1 = (l_int32)(L_ABS(fw * sina + fh * cosa) + 0.5);
275 h2 = (l_int32)(L_ABS(-fw * sina + fh * cosa) + 0.5);
276 wnew = L_MAX(w, L_MAX(w1, w2));
277 hnew = L_MAX(h, L_MAX(h1, h2));
279 if ((pixd = pixCreate(wnew, hnew, d)) == NULL)
280 return (
PIX *)ERROR_PTR(
"pixd not made", __func__, NULL);
281 pixCopyResolution(pixd, pixs);
282 pixCopyColormap(pixd, pixs);
283 pixCopySpp(pixd, pixs);
284 pixCopyText(pixd, pixs);
285 xoff = (wnew - w) / 2;
286 yoff = (hnew - h) / 2;
290 pixSetBlackOrWhite(pixd, setcolor);
293 pixRasterop(pixd, xoff, yoff, w, h,
PIX_SRC, pixs, 0, 0);
326l_int32 w, h, d, i, j, x, y, xdif, ydif, wm1, hm1, wpld;
329l_uint32 *datad, *lined;
334 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
336 return (
PIX *)ERROR_PTR(
"invalid incolor", __func__, NULL);
337 pixGetDimensions(pixs, &w, &h, &d);
338 if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
339 return (
PIX *)ERROR_PTR(
"invalid depth", __func__, NULL);
341 if (L_ABS(angle) < MinAngleToRotate)
342 return pixClone(pixs);
344 if ((pixd = pixCreateTemplate(pixs)) == NULL)
345 return (
PIX *)ERROR_PTR(
"pixd not made", __func__, NULL);
346 pixSetBlackOrWhite(pixd, incolor);
350 datad = pixGetData(pixd);
351 wpld = pixGetWpl(pixd);
354 lines = pixGetLinePtrs(pixs, NULL);
358 for (i = 0; i < h; i++) {
359 lined = datad + i * wpld;
361 for (j = 0; j < w; j++) {
363 x = xcen + (l_int32)(-xdif * cosa - ydif * sina);
364 if (x < 0 || x > wm1)
continue;
365 y = ycen + (l_int32)(-ydif * cosa + xdif * sina);
366 if (y < 0 || y > hm1)
continue;
380 for (i = 0; i < h; i++) {
381 lined = datad + i * wpld;
383 for (j = 0; j < w; j++) {
385 x = xcen + (l_int32)(-xdif * cosa - ydif * sina);
386 if (x < 0 || x > wm1)
continue;
387 y = ycen + (l_int32)(-ydif * cosa + xdif * sina);
388 if (y < 0 || y > hm1)
continue;
412 return (
PIX *)ERROR_PTR(
"invalid depth", __func__, NULL);
455PIX *pix1, *pix2, *pix3, *pix4, *pixd;
457 if (!pixs || pixGetDepth(pixs) != 1)
458 return (
PIX *)ERROR_PTR(
"pixs undefined or not 1 bpp", __func__, NULL);
460 return (
PIX *)ERROR_PTR(
"invalid incolor", __func__, NULL);
462 pix1 = pixConvertTo8(pixs, 0);
463 pix2 = pixBlockconv(pix1, 1, 1);
464 pix3 = pixRotateAM(pix2, angle, incolor);
465 pix4 = pixUnsharpMasking(pix3, 1, 1.0);
466 pixd = pixThresholdToBinary(pix4, 128);
532l_int32 ws, hs, d, spp;
533PIX *pixd, *pix32, *pixg2, *pixgr;
536 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
537 pixGetDimensions(pixs, &ws, &hs, &d);
538 if (d != 32 && pixGetColormap(pixs) == NULL)
539 return (
PIX *)ERROR_PTR(
"pixs not cmapped or 32 bpp", __func__, NULL);
540 if (pixg && pixGetDepth(pixg) != 8) {
541 L_WARNING(
"pixg not 8 bpp; using 'fract' transparent alpha\n",
545 if (!pixg && (fract < 0.0 || fract > 1.0)) {
546 L_WARNING(
"invalid fract; using fully opaque\n", __func__);
549 if (!pixg && fract == 0.0)
550 L_WARNING(
"transparent alpha; image will not be blended\n", __func__);
554 pix32 = pixConvertTo32(pixs);
556 pix32 = pixClone(pixs);
557 spp = pixGetSpp(pix32);
560 pixSetSpp(pix32, spp);
565 pixg2 = pixCreate(ws, hs, 8);
568 else if (fract > 0.0)
569 pixSetAllArbitrary(pixg2, (l_int32)(255.0 * fract));
571 pixg2 = pixResizeToMatch(pixg, NULL, ws, hs);
573 if (ws > 10 && hs > 10) {
574 pixSetBorderRingVal(pixg2, 1,
575 (l_int32)(255.0 * fract * AlphaMaskBorderVals[0]));
576 pixSetBorderRingVal(pixg2, 2,
577 (l_int32)(255.0 * fract * AlphaMaskBorderVals[1]));
#define GET_DATA_QBIT(pdata, n)
#define GET_DATA_TWO_BYTES(pdata, n)
#define SET_DATA_BIT(pdata, n)
#define SET_DATA_DIBIT(pdata, n, val)
#define SET_DATA_TWO_BYTES(pdata, n, val)
#define SET_DATA_FOUR_BYTES(pdata, n, val)
#define GET_DATA_BYTE(pdata, n)
#define GET_DATA_FOUR_BYTES(pdata, n)
#define GET_DATA_DIBIT(pdata, n)
#define SET_DATA_BYTE(pdata, n, val)
#define CLEAR_DATA_BIT(pdata, n)
#define GET_DATA_BIT(pdata, n)
#define SET_DATA_QBIT(pdata, n, val)
@ REMOVE_CMAP_BASED_ON_SRC
PIX * pixEmbedForRotation(PIX *pixs, l_float32 angle, l_int32 incolor, l_int32 width, l_int32 height)
pixEmbedForRotation()
PIX * pixRotateBySampling(PIX *pixs, l_int32 xcen, l_int32 ycen, l_float32 angle, l_int32 incolor)
pixRotateBySampling()
PIX * pixRotateWithAlpha(PIX *pixs, l_float32 angle, PIX *pixg, l_float32 fract)
pixRotateWithAlpha()
PIX * pixRotateBinaryNice(PIX *pixs, l_float32 angle, l_int32 incolor)
pixRotateBinaryNice()
PIX * pixRotate(PIX *pixs, l_float32 angle, l_int32 type, l_int32 incolor, l_int32 width, l_int32 height)
pixRotate()