Leptonica  1.82.0
Image processing and image analysis suite
pix1.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  -
4  - Redistribution and use in source and binary forms, with or without
5  - modification, are permitted provided that the following conditions
6  - are met:
7  - 1. Redistributions of source code must retain the above copyright
8  - notice, this list of conditions and the following disclaimer.
9  - 2. Redistributions in binary form must reproduce the above
10  - copyright notice, this list of conditions and the following
11  - disclaimer in the documentation and/or other materials
12  - provided with the distribution.
13  -
14  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18  - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
198 #ifdef HAVE_CONFIG_H
199 #include <config_auto.h>
200 #endif /* HAVE_CONFIG_H */
201 
202 #include <string.h>
203 #include "allheaders.h"
204 
205 static void pixFree(PIX *pix);
206 
207 /*-------------------------------------------------------------------------*
208  * Pix Memory Management *
209  * *
210  * These functions give you the freedom to specify at compile or run *
211  * time the allocator and deallocator to be used for the pix raster *
212  * image data. They have no effect on any other heap allocation, *
213  * including the pix struct itself, which is controlled by the *
214  * #defines in environ.h. *
215  * *
216  * The default functions for allocating pix raster data are malloc and *
217  * free (or leptonica_* custom allocators if LEPTONICA_INTERCEPT_ALLOC *
218  * is defined). Use setPixMemoryManager() to specify other functions *
219  * to use specifically for pix raster image data. *
220  *-------------------------------------------------------------------------*/
222  /*
223  * <pre>
224  * Notes:
225  * (1) The allocator and deallocator function types,
226  * alloc_fn and dealloc_fn, are defined in pix.h.
227  * </pre>
228  */
230 {
231  alloc_fn allocator;
232  dealloc_fn deallocator;
233 };
234 
237 #ifdef LEPTONICA_INTERCEPT_ALLOC
238  &leptonica_malloc,
239  &leptonica_free
240 #else
241  &malloc,
242  &free
243 #endif /* LEPTONICA_INTERCEPT_ALLOC */
244 };
245 
246 static void *
247 pixdata_malloc(size_t size)
248 {
249 #ifndef _MSC_VER
250  return (*pix_mem_manager.allocator)(size);
251 #else /* _MSC_VER */
252  /* Under MSVC++, pix_mem_manager is initialized after a call to
253  * pixdata_malloc. Just ignore the custom allocator feature. */
254  return LEPT_MALLOC(size);
255 #endif /* _MSC_VER */
256 }
257 
258 static void
259 pixdata_free(void *ptr)
260 {
261 #ifndef _MSC_VER
262  (*pix_mem_manager.deallocator)(ptr);
263 #else /* _MSC_VER */
264  /* Under MSVC++, pix_mem_manager is initialized after a call to
265  * pixdata_malloc. Just ignore the custom allocator feature. */
266  LEPT_FREE(ptr);
267 #endif /* _MSC_VER */
268 }
269 
295 void
297  dealloc_fn deallocator)
298 {
299  if (allocator) pix_mem_manager.allocator = allocator;
300  if (deallocator) pix_mem_manager.deallocator = deallocator;
301 }
302 
303 
304 /*--------------------------------------------------------------------*
305  * Pix Creation *
306  *--------------------------------------------------------------------*/
314 PIX *
315 pixCreate(l_int32 width,
316  l_int32 height,
317  l_int32 depth)
318 {
319 PIX *pixd;
320 
321  PROCNAME("pixCreate");
322 
323  if ((pixd = pixCreateNoInit(width, height, depth)) == NULL)
324  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
325  memset(pixd->data, 0, 4LL * pixd->wpl * pixd->h);
326  return pixd;
327 }
328 
329 
345 PIX *
346 pixCreateNoInit(l_int32 width,
347  l_int32 height,
348  l_int32 depth)
349 {
350 l_int32 wpl;
351 PIX *pixd;
352 l_uint32 *data;
353 
354  PROCNAME("pixCreateNoInit");
355  if ((pixd = pixCreateHeader(width, height, depth)) == NULL)
356  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
357  wpl = pixGetWpl(pixd);
358  if ((data = (l_uint32 *)pixdata_malloc(4LL * wpl * height)) == NULL) {
359  pixDestroy(&pixd);
360  return (PIX *)ERROR_PTR("pixdata_malloc fail for data",
361  procName, NULL);
362  }
363  pixSetData(pixd, data);
364  pixSetPadBits(pixd, 0);
365  return pixd;
366 }
367 
368 
382 PIX *
383 pixCreateTemplate(const PIX *pixs)
384 {
385 PIX *pixd;
386 
387  PROCNAME("pixCreateTemplate");
388 
389  if (!pixs)
390  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
391 
392  if ((pixd = pixCreateTemplateNoInit(pixs)) == NULL)
393  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
394  memset(pixd->data, 0, 4LL * pixd->wpl * pixd->h);
395  return pixd;
396 }
397 
398 
416 PIX *
418 {
419 l_int32 w, h, d;
420 PIX *pixd;
421 
422  PROCNAME("pixCreateTemplateNoInit");
423 
424  if (!pixs)
425  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
426 
427  pixGetDimensions(pixs, &w, &h, &d);
428  if ((pixd = pixCreateNoInit(w, h, d)) == NULL)
429  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
430  pixCopySpp(pixd, pixs);
431  pixCopyResolution(pixd, pixs);
432  pixCopyColormap(pixd, pixs);
433  pixCopyText(pixd, pixs);
434  pixCopyInputFormat(pixd, pixs);
435  pixSetPadBits(pixd, 0);
436  return pixd;
437 }
438 
439 
457 PIX *
458 pixCreateWithCmap(l_int32 width,
459  l_int32 height,
460  l_int32 depth,
461  l_int32 initcolor)
462 {
463 PIX *pix;
464 PIXCMAP *cmap;
465 
466  PROCNAME("pixCreateWithCmap");
467 
468  if (depth != 2 && depth != 4 && depth != 8)
469  return (PIX *)ERROR_PTR("depth not 2, 4 or 8 bpp", procName, NULL);
470 
471  if ((pix = pixCreate(width, height, depth)) == NULL)
472  return (PIX *)ERROR_PTR("pix not made", procName, NULL);
473  cmap = pixcmapCreate(depth);
474  pixSetColormap(pix, cmap);
475  if (initcolor == L_SET_BLACK)
476  pixcmapAddColor(cmap, 0, 0, 0);
477  else /* L_SET_WHITE */
478  pixcmapAddColor(cmap, 255, 255, 255);
479  return pix;
480 }
481 
482 
503 PIX *
504 pixCreateHeader(l_int32 width,
505  l_int32 height,
506  l_int32 depth)
507 {
508 l_int32 wpl;
509 l_uint64 wpl64, bignum;
510 PIX *pixd;
511 
512  PROCNAME("pixCreateHeader");
513 
514  if ((depth != 1) && (depth != 2) && (depth != 4) && (depth != 8)
515  && (depth != 16) && (depth != 24) && (depth != 32))
516  return (PIX *)ERROR_PTR("depth must be {1, 2, 4, 8, 16, 24, 32}",
517  procName, NULL);
518  if (width <= 0)
519  return (PIX *)ERROR_PTR("width must be > 0", procName, NULL);
520  if (height <= 0)
521  return (PIX *)ERROR_PTR("height must be > 0", procName, NULL);
522 
523  /* Avoid overflow in malloc, malicious or otherwise */
524  wpl64 = ((l_uint64)width * (l_uint64)depth + 31) / 32;
525  if (wpl64 > ((1LL << 24) - 1)) {
526  L_ERROR("requested w = %d, h = %d, d = %d\n",
527  procName, width, height, depth);
528  return (PIX *)ERROR_PTR("wpl >= 2^24", procName, NULL);
529  }
530  wpl = (l_int32)wpl64;
531  bignum = 4LL * wpl * height; /* number of bytes to be requested */
532  if (bignum > ((1LL << 31) - 1)) {
533  L_ERROR("requested w = %d, h = %d, d = %d\n",
534  procName, width, height, depth);
535  return (PIX *)ERROR_PTR("requested bytes >= 2^31", procName, NULL);
536  }
537 
538 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
539  if (bignum > (1LL << 26)) {
540  L_ERROR("fuzzer requested > 64 MB; refused\n", procName);
541  return NULL;
542  }
543  if (width > 20000) {
544  L_ERROR("fuzzer requested width > 20K; refused\n", procName);
545  return NULL;
546  }
547  if (height > 20000) {
548  L_ERROR("fuzzer requested height > 20K; refused\n", procName);
549  return NULL;
550  }
551 #endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
552 
553  pixd = (PIX *)LEPT_CALLOC(1, sizeof(PIX));
554  pixSetWidth(pixd, width);
555  pixSetHeight(pixd, height);
556  pixSetDepth(pixd, depth);
557  pixSetWpl(pixd, wpl);
558  if (depth == 24 || depth == 32)
559  pixSetSpp(pixd, 3);
560  else
561  pixSetSpp(pixd, 1);
562  pixd->refcount = 1;
563  pixd->informat = IFF_UNKNOWN;
564  return pixd;
565 }
566 
567 
592 PIX *
593 pixClone(PIX *pixs)
594 {
595  PROCNAME("pixClone");
596 
597  if (!pixs)
598  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
599  pixChangeRefcount(pixs, 1);
600 
601  return pixs;
602 }
603 
604 
605 /*--------------------------------------------------------------------*
606  * Pix Destruction *
607  *--------------------------------------------------------------------*/
620 void
622 {
623 PIX *pix;
624 
625  PROCNAME("pixDestroy");
626 
627  if (!ppix) {
628  L_WARNING("ptr address is null!\n", procName);
629  return;
630  }
631 
632  if ((pix = *ppix) == NULL)
633  return;
634  pixFree(pix);
635  *ppix = NULL;
636 }
637 
638 
650 static void
652 {
653 l_uint32 *data;
654 char *text;
655 
656  if (!pix) return;
657 
658  pixChangeRefcount(pix, -1);
659  if (pixGetRefcount(pix) <= 0) {
660  if ((data = pixGetData(pix)) != NULL)
661  pixdata_free(data);
662  if ((text = pixGetText(pix)) != NULL)
663  LEPT_FREE(text);
664  pixDestroyColormap(pix);
665  LEPT_FREE(pix);
666  }
667  return;
668 }
669 
670 
671 /*-------------------------------------------------------------------------*
672  * Pix Copy *
673  *-------------------------------------------------------------------------*/
704 PIX *
705 pixCopy(PIX *pixd, /* can be null */
706  const PIX *pixs)
707 {
708 l_int32 bytes;
709 
710  PROCNAME("pixCopy");
711 
712  if (!pixs)
713  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
714  if (pixs == pixd)
715  return pixd;
716 
717  /* Total bytes in image data */
718  bytes = 4 * pixGetWpl(pixs) * pixGetHeight(pixs);
719 
720  /* If we're making a new pix ... */
721  if (!pixd) {
722  if ((pixd = pixCreateTemplate(pixs)) == NULL)
723  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
724  memcpy(pixd->data, pixs->data, bytes);
725  return pixd;
726  }
727 
728  /* Reallocate image data if sizes are different. If this fails,
729  * pixd hasn't been changed. But we want to signal that the copy
730  * failed, so return NULL. This will cause a memory leak if the
731  * return ptr is assigned to pixd, but that is preferred to proceeding
732  * with an incorrect pixd, and in any event this use case of
733  * pixCopy() -- reallocating into an existing pix -- is infrequent. */
734  if (pixResizeImageData(pixd, pixs) == 1)
735  return (PIX *)ERROR_PTR("reallocation of data failed", procName, NULL);
736 
737  /* Copy non-image data fields */
738  pixCopyColormap(pixd, pixs);
739  pixCopySpp(pixd, pixs);
740  pixCopyResolution(pixd, pixs);
741  pixCopyInputFormat(pixd, pixs);
742  pixCopyText(pixd, pixs);
743 
744  /* Copy image data */
745  memcpy(pixd->data, pixs->data, bytes);
746  return pixd;
747 }
748 
749 
767 l_ok
769  const PIX *pixs)
770 {
771 l_int32 w, h, d, wpl, bytes;
772 l_uint32 *data;
773 
774  PROCNAME("pixResizeImageData");
775 
776  if (!pixs)
777  return ERROR_INT("pixs not defined", procName, 1);
778  if (!pixd)
779  return ERROR_INT("pixd not defined", procName, 1);
780 
781  if (pixSizesEqual(pixs, pixd)) /* nothing to do */
782  return 0;
783 
784  /* Make sure we can copy the data */
785  pixGetDimensions(pixs, &w, &h, &d);
786  wpl = pixGetWpl(pixs);
787  bytes = 4 * wpl * h;
788  if ((data = (l_uint32 *)pixdata_malloc(bytes)) == NULL)
789  return ERROR_INT("pixdata_malloc fail for data", procName, 1);
790 
791  /* OK, do it */
792  pixSetWidth(pixd, w);
793  pixSetHeight(pixd, h);
794  pixSetDepth(pixd, d);
795  pixSetWpl(pixd, wpl);
796  pixFreeData(pixd); /* free any existing image data */
797  pixSetData(pixd, data); /* set the uninitialized memory buffer */
798  pixCopyResolution(pixd, pixs);
799  return 0;
800 }
801 
802 
815 l_ok
817  const PIX *pixs)
818 {
819 l_int32 valid;
820 const PIXCMAP *cmaps;
821 PIXCMAP *cmapd;
822 
823  PROCNAME("pixCopyColormap");
824 
825  if (!pixs)
826  return ERROR_INT("pixs not defined", procName, 1);
827  if (!pixd)
828  return ERROR_INT("pixd not defined", procName, 1);
829  if (pixs == pixd)
830  return 0; /* no-op */
831  if (pixGetDepth(pixs) != pixGetDepth(pixd))
832  return ERROR_INT("depths of pixs and pixd differ", procName, 1);
833 
834  pixDestroyColormap(pixd);
835  if ((cmaps = pixs->colormap) == NULL) /* not an error */
836  return 0;
837  pixcmapIsValid(cmaps, NULL, &valid);
838  if (!valid)
839  return ERROR_INT("cmap not valid", procName, 1);
840 
841  if ((cmapd = pixcmapCopy(cmaps)) == NULL)
842  return ERROR_INT("cmapd not made", procName, 1);
843  pixSetColormap(pixd, cmapd);
844  return 0;
845 }
846 
847 
901 l_ok
903  PIX **ppixs,
904  l_int32 copytext,
905  l_int32 copyformat)
906 {
907 l_int32 nbytes;
908 PIX *pixs;
909 
910  PROCNAME("pixTransferAllData");
911 
912  if (!ppixs)
913  return ERROR_INT("&pixs not defined", procName, 1);
914  if ((pixs = *ppixs) == NULL)
915  return ERROR_INT("pixs not defined", procName, 1);
916  if (!pixd)
917  return ERROR_INT("pixd not defined", procName, 1);
918  if (pixs == pixd) /* no-op */
919  return ERROR_INT("pixd == pixs", procName, 1);
920 
921  if (pixGetRefcount(pixs) == 1) { /* transfer the data, cmap, text */
922  pixFreeData(pixd); /* dealloc any existing data */
923  pixSetData(pixd, pixGetData(pixs)); /* transfer new data from pixs */
924  pixs->data = NULL; /* pixs no longer owns data */
925  pixDestroyColormap(pixd); /* free the old one, if it exists */
926  pixd->colormap = pixGetColormap(pixs); /* transfer to pixd */
927  pixs->colormap = NULL; /* pixs no longer owns colormap */
928  if (copytext) {
929  pixSetText(pixd, pixGetText(pixs));
930  pixSetText(pixs, NULL);
931  }
932  } else { /* preserve pixs by making a copy of the data, cmap, text */
933  pixResizeImageData(pixd, pixs);
934  nbytes = 4 * pixGetWpl(pixs) * pixGetHeight(pixs);
935  memcpy(pixGetData(pixd), pixGetData(pixs), nbytes);
936  pixCopyColormap(pixd, pixs);
937  if (copytext)
938  pixCopyText(pixd, pixs);
939  }
940 
941  pixCopySpp(pixd, pixs);
942  pixCopyResolution(pixd, pixs);
943  pixCopyDimensions(pixd, pixs);
944  if (copyformat)
945  pixCopyInputFormat(pixd, pixs);
946 
947  /* This will destroy pixs if data was transferred;
948  * otherwise, it just decrements its refcount. */
949  pixDestroy(ppixs);
950  return 0;
951 }
952 
953 
992 l_ok
994  PIX **ppixs)
995 {
996  PROCNAME("pixSwapAndDestroy");
997 
998  if (!ppixd)
999  return ERROR_INT("&pixd not defined", procName, 1);
1000  if (!ppixs)
1001  return ERROR_INT("&pixs not defined", procName, 1);
1002  if (*ppixs == NULL)
1003  return ERROR_INT("pixs not defined", procName, 1);
1004  if (ppixs == ppixd) /* no-op */
1005  return ERROR_INT("&pixd == &pixs", procName, 1);
1006 
1007  pixDestroy(ppixd);
1008  *ppixd = pixClone(*ppixs);
1009  pixDestroy(ppixs);
1010  return 0;
1011 }
1012 
1013 
1014 /*--------------------------------------------------------------------*
1015  * Pix Accessors *
1016  *--------------------------------------------------------------------*/
1017 l_int32
1018 pixGetWidth(const PIX *pix)
1019 {
1020  PROCNAME("pixGetWidth");
1021 
1022  if (!pix)
1023  return ERROR_INT("pix not defined", procName, 0);
1024 
1025  return pix->w;
1026 }
1027 
1028 
1029 l_int32
1030 pixSetWidth(PIX *pix,
1031  l_int32 width)
1032 {
1033  PROCNAME("pixSetWidth");
1034 
1035  if (!pix)
1036  return ERROR_INT("pix not defined", procName, 1);
1037  if (width < 0) {
1038  pix->w = 0;
1039  return ERROR_INT("width must be >= 0", procName, 1);
1040  }
1041 
1042  pix->w = width;
1043  return 0;
1044 }
1045 
1046 
1047 l_int32
1048 pixGetHeight(const PIX *pix)
1049 {
1050  PROCNAME("pixGetHeight");
1051 
1052  if (!pix)
1053  return ERROR_INT("pix not defined", procName, 0);
1054 
1055  return pix->h;
1056 }
1057 
1058 
1059 l_int32
1060 pixSetHeight(PIX *pix,
1061  l_int32 height)
1062 {
1063  PROCNAME("pixSetHeight");
1064 
1065  if (!pix)
1066  return ERROR_INT("pix not defined", procName, 1);
1067  if (height < 0) {
1068  pix->h = 0;
1069  return ERROR_INT("h must be >= 0", procName, 1);
1070  }
1071 
1072  pix->h = height;
1073  return 0;
1074 }
1075 
1076 
1077 l_int32
1078 pixGetDepth(const PIX *pix)
1079 {
1080  PROCNAME("pixGetDepth");
1081 
1082  if (!pix)
1083  return ERROR_INT("pix not defined", procName, 0);
1084 
1085  return pix->d;
1086 }
1087 
1088 
1089 l_int32
1090 pixSetDepth(PIX *pix,
1091  l_int32 depth)
1092 {
1093  PROCNAME("pixSetDepth");
1094 
1095  if (!pix)
1096  return ERROR_INT("pix not defined", procName, 1);
1097  if (depth < 1)
1098  return ERROR_INT("d must be >= 1", procName, 1);
1099 
1100  pix->d = depth;
1101  return 0;
1102 }
1103 
1104 
1112 l_ok
1114  l_int32 *pw,
1115  l_int32 *ph,
1116  l_int32 *pd)
1117 {
1118  PROCNAME("pixGetDimensions");
1119 
1120  if (pw) *pw = 0;
1121  if (ph) *ph = 0;
1122  if (pd) *pd = 0;
1123  if (!pix)
1124  return ERROR_INT("pix not defined", procName, 1);
1125  if (pw) *pw = pix->w;
1126  if (ph) *ph = pix->h;
1127  if (pd) *pd = pix->d;
1128  return 0;
1129 }
1130 
1131 
1139 l_ok
1141  l_int32 w,
1142  l_int32 h,
1143  l_int32 d)
1144 {
1145  PROCNAME("pixSetDimensions");
1146 
1147  if (!pix)
1148  return ERROR_INT("pix not defined", procName, 1);
1149  if (w > 0) pixSetWidth(pix, w);
1150  if (h > 0) pixSetHeight(pix, h);
1151  if (d > 0) pixSetDepth(pix, d);
1152  return 0;
1153 }
1154 
1155 
1163 l_ok
1165  const PIX *pixs)
1166 {
1167  PROCNAME("pixCopyDimensions");
1168 
1169  if (!pixd)
1170  return ERROR_INT("pixd not defined", procName, 1);
1171  if (!pixs)
1172  return ERROR_INT("pixs not defined", procName, 1);
1173  if (pixs == pixd)
1174  return 0; /* no-op */
1175 
1176  pixSetWidth(pixd, pixGetWidth(pixs));
1177  pixSetHeight(pixd, pixGetHeight(pixs));
1178  pixSetDepth(pixd, pixGetDepth(pixs));
1179  pixSetWpl(pixd, pixGetWpl(pixs));
1180  return 0;
1181 }
1182 
1183 
1184 l_int32
1185 pixGetSpp(const PIX *pix)
1186 {
1187  PROCNAME("pixGetSpp");
1188 
1189  if (!pix)
1190  return ERROR_INT("pix not defined", procName, 0);
1191 
1192  return pix->spp;
1193 }
1194 
1195 
1196 /*
1197  * \brief pixSetSpp()
1198  *
1199  * \param[in] pix
1200  * \param[in] spp 1, 3 or 4 samples
1201  * \return 0 if OK, 1 on error
1202  *
1203  * <pre>
1204  * Notes:
1205  * (1) For a 32 bpp pix, this can be used to ignore the
1206  * alpha sample (spp == 3) or to use it (spp == 4).
1207  * For example, to write a spp == 4 image without the alpha
1208  * sample (as an rgb pix), call pixSetSpp(pix, 3) and
1209  * then write it out as a png.
1210  * </pre>
1211  */
1212 l_int32
1213 pixSetSpp(PIX *pix,
1214  l_int32 spp)
1215 {
1216  PROCNAME("pixSetSpp");
1217 
1218  if (!pix)
1219  return ERROR_INT("pix not defined", procName, 1);
1220  if (spp < 1)
1221  return ERROR_INT("spp must be >= 1", procName, 1);
1222 
1223  pix->spp = spp;
1224  return 0;
1225 }
1226 
1227 
1235 l_ok
1237  const PIX *pixs)
1238 {
1239  PROCNAME("pixCopySpp");
1240 
1241  if (!pixd)
1242  return ERROR_INT("pixd not defined", procName, 1);
1243  if (!pixs)
1244  return ERROR_INT("pixs not defined", procName, 1);
1245  if (pixs == pixd)
1246  return 0; /* no-op */
1247 
1248  pixSetSpp(pixd, pixGetSpp(pixs));
1249  return 0;
1250 }
1251 
1252 
1253 l_int32
1254 pixGetWpl(const PIX *pix)
1255 {
1256  PROCNAME("pixGetWpl");
1257 
1258  if (!pix)
1259  return ERROR_INT("pix not defined", procName, 0);
1260  return pix->wpl;
1261 }
1262 
1263 
1264 l_int32
1265 pixSetWpl(PIX *pix,
1266  l_int32 wpl)
1267 {
1268  PROCNAME("pixSetWpl");
1269 
1270  if (!pix)
1271  return ERROR_INT("pix not defined", procName, 1);
1272 
1273  pix->wpl = wpl;
1274  return 0;
1275 }
1276 
1277 
1278 l_int32
1279 pixGetRefcount(const PIX *pix)
1280 {
1281  PROCNAME("pixGetRefcount");
1282 
1283  if (!pix)
1284  return ERROR_INT("pix not defined", procName, 0);
1285  return pix->refcount;
1286 }
1287 
1288 
1289 l_int32
1290 pixChangeRefcount(PIX *pix,
1291  l_int32 delta)
1292 {
1293  PROCNAME("pixChangeRefcount");
1294 
1295  if (!pix)
1296  return ERROR_INT("pix not defined", procName, 1);
1297 
1298  pix->refcount += delta;
1299  return 0;
1300 }
1301 
1302 
1303 l_int32
1304 pixGetXRes(const PIX *pix)
1305 {
1306  PROCNAME("pixGetXRes");
1307 
1308  if (!pix)
1309  return ERROR_INT("pix not defined", procName, 0);
1310  return pix->xres;
1311 }
1312 
1313 
1314 l_int32
1315 pixSetXRes(PIX *pix,
1316  l_int32 res)
1317 {
1318  PROCNAME("pixSetXRes");
1319 
1320  if (!pix)
1321  return ERROR_INT("pix not defined", procName, 1);
1322 
1323  pix->xres = res;
1324  return 0;
1325 }
1326 
1327 
1328 l_int32
1329 pixGetYRes(const PIX *pix)
1330 {
1331  PROCNAME("pixGetYRes");
1332 
1333  if (!pix)
1334  return ERROR_INT("pix not defined", procName, 0);
1335  return pix->yres;
1336 }
1337 
1338 
1339 l_int32
1340 pixSetYRes(PIX *pix,
1341  l_int32 res)
1342 {
1343  PROCNAME("pixSetYRes");
1344 
1345  if (!pix)
1346  return ERROR_INT("pix not defined", procName, 1);
1347 
1348  pix->yres = res;
1349  return 0;
1350 }
1351 
1352 
1360 l_ok
1362  l_int32 *pxres,
1363  l_int32 *pyres)
1364 {
1365  PROCNAME("pixGetResolution");
1366 
1367  if (pxres) *pxres = 0;
1368  if (pyres) *pyres = 0;
1369  if (!pxres && !pyres)
1370  return ERROR_INT("no output requested", procName, 1);
1371  if (!pix)
1372  return ERROR_INT("pix not defined", procName, 1);
1373  if (pxres) *pxres = pix->xres;
1374  if (pyres) *pyres = pix->yres;
1375  return 0;
1376 }
1377 
1378 
1386 l_ok
1388  l_int32 xres,
1389  l_int32 yres)
1390 {
1391  PROCNAME("pixSetResolution");
1392 
1393  if (!pix)
1394  return ERROR_INT("pix not defined", procName, 1);
1395  if (xres > 0) pix->xres = xres;
1396  if (yres > 0) pix->yres = yres;
1397  return 0;
1398 }
1399 
1400 
1401 l_int32
1402 pixCopyResolution(PIX *pixd,
1403  const PIX *pixs)
1404 {
1405  PROCNAME("pixCopyResolution");
1406 
1407  if (!pixs)
1408  return ERROR_INT("pixs not defined", procName, 1);
1409  if (!pixd)
1410  return ERROR_INT("pixd not defined", procName, 1);
1411  if (pixs == pixd)
1412  return 0; /* no-op */
1413 
1414  pixSetXRes(pixd, pixGetXRes(pixs));
1415  pixSetYRes(pixd, pixGetYRes(pixs));
1416  return 0;
1417 }
1418 
1419 
1420 l_int32
1421 pixScaleResolution(PIX *pix,
1422  l_float32 xscale,
1423  l_float32 yscale)
1424 {
1425 l_float64 xres, yres;
1426 l_float64 maxres = 100000000.0;
1427 
1428  PROCNAME("pixScaleResolution");
1429 
1430  if (!pix)
1431  return ERROR_INT("pix not defined", procName, 1);
1432  if (xscale <= 0 || yscale <= 0)
1433  return ERROR_INT("invalid scaling ratio", procName, 1);
1434 
1435  xres = (l_float64)xscale * (l_float32)(pix->xres) + 0.5;
1436  yres = (l_float64)yscale * (l_float32)(pix->yres) + 0.5;
1437  pix->xres = (l_uint32)L_MIN(xres, maxres);
1438  pix->yres = (l_uint32)L_MIN(yres, maxres);
1439  return 0;
1440 }
1441 
1442 
1443 l_int32
1444 pixGetInputFormat(const PIX *pix)
1445 {
1446  PROCNAME("pixGetInputFormat");
1447 
1448  if (!pix)
1449  return ERROR_INT("pix not defined", procName, 0);
1450  return pix->informat;
1451 }
1452 
1453 
1454 l_int32
1455 pixSetInputFormat(PIX *pix,
1456  l_int32 informat)
1457 {
1458  PROCNAME("pixSetInputFormat");
1459 
1460  if (!pix)
1461  return ERROR_INT("pix not defined", procName, 1);
1462  pix->informat = informat;
1463  return 0;
1464 }
1465 
1466 
1467 l_int32
1468 pixCopyInputFormat(PIX *pixd,
1469  const PIX *pixs)
1470 {
1471  PROCNAME("pixCopyInputFormat");
1472 
1473  if (!pixs)
1474  return ERROR_INT("pixs not defined", procName, 1);
1475  if (!pixd)
1476  return ERROR_INT("pixd not defined", procName, 1);
1477  if (pixs == pixd)
1478  return 0; /* no-op */
1479 
1480  pixSetInputFormat(pixd, pixGetInputFormat(pixs));
1481  return 0;
1482 }
1483 
1484 
1485 l_int32
1486 pixSetSpecial(PIX *pix,
1487  l_int32 special)
1488 {
1489  PROCNAME("pixSetSpecial");
1490 
1491  if (!pix)
1492  return ERROR_INT("pix not defined", procName, 1);
1493  pix->special = special;
1494  return 0;
1495 }
1496 
1497 
1511 char *
1513 {
1514  PROCNAME("pixGetText");
1515 
1516  if (!pix)
1517  return (char *)ERROR_PTR("pix not defined", procName, NULL);
1518  return pix->text;
1519 }
1520 
1521 
1535 l_ok
1537  const char *textstring)
1538 {
1539  PROCNAME("pixSetText");
1540 
1541  if (!pix)
1542  return ERROR_INT("pix not defined", procName, 1);
1543 
1544  stringReplace(&pix->text, textstring);
1545  return 0;
1546 }
1547 
1548 
1563 l_ok
1565  const char *textstring)
1566 {
1567 char *newstring;
1568 
1569  PROCNAME("pixAddText");
1570 
1571  if (!pix)
1572  return ERROR_INT("pix not defined", procName, 1);
1573 
1574  newstring = stringJoin(pixGetText(pix), textstring);
1575  stringReplace(&pix->text, newstring);
1576  LEPT_FREE(newstring);
1577  return 0;
1578 }
1579 
1580 
1581 l_int32
1582 pixCopyText(PIX *pixd,
1583  const PIX *pixs)
1584 {
1585  PROCNAME("pixCopyText");
1586 
1587  if (!pixs)
1588  return ERROR_INT("pixs not defined", procName, 1);
1589  if (!pixd)
1590  return ERROR_INT("pixd not defined", procName, 1);
1591  if (pixs == pixd)
1592  return 0; /* no-op */
1593 
1594  pixSetText(pixd, pixs->text);
1595  return 0;
1596 }
1597 
1598 
1616 l_uint8 *
1618  size_t *psize)
1619 {
1620 char *str;
1621 
1622  PROCNAME("pixGetTextCompNew");
1623 
1624  if (!pix)
1625  return (l_uint8 *)ERROR_PTR("pix not defined", procName, NULL);
1626  str = pixGetText(pix);
1627  return decodeAscii85WithComp(str, strlen(str), psize);
1628 }
1629 
1630 
1647 l_ok
1649  const l_uint8 *data,
1650  size_t size)
1651 {
1652 size_t encodesize; /* ignored */
1653 
1654  PROCNAME("pixSetTextCompNew");
1655 
1656  if (!pix)
1657  return ERROR_INT("pix not defined", procName, 1);
1658 
1659  stringReplace(&pix->text, encodeAscii85WithComp(data, size, &encodesize));
1660  return 0;
1661 }
1662 
1663 
1664 PIXCMAP *
1665 pixGetColormap(PIX *pix)
1666 {
1667  PROCNAME("pixGetColormap");
1668 
1669  if (!pix)
1670  return (PIXCMAP *)ERROR_PTR("pix not defined", procName, NULL);
1671  return pix->colormap;
1672 }
1673 
1674 
1698 l_ok
1700  PIXCMAP *colormap)
1701 {
1702 l_int32 valid;
1703 
1704  PROCNAME("pixSetColormap");
1705 
1706  if (!pix)
1707  return ERROR_INT("pix not defined", procName, 1);
1708  if (!colormap) return 0;
1709 
1710  /* Make sure the colormap doesn't get lost */
1711  pixDestroyColormap(pix);
1712  pix->colormap = colormap;
1713 
1714  pixcmapIsValid(colormap, NULL, &valid);
1715  if (!valid)
1716  return ERROR_INT("colormap is not valid", procName, 1);
1717  return 0;
1718 }
1719 
1720 
1727 l_ok
1729 {
1730 PIXCMAP *cmap;
1731 
1732  PROCNAME("pixDestroyColormap");
1733 
1734  if (!pix)
1735  return ERROR_INT("pix not defined", procName, 1);
1736 
1737  if ((cmap = pix->colormap) != NULL) {
1738  pixcmapDestroy(&cmap);
1739  pix->colormap = NULL;
1740  }
1741  return 0;
1742 }
1743 
1744 
1762 l_uint32 *
1764 {
1765  PROCNAME("pixGetData");
1766 
1767  if (!pix)
1768  return (l_uint32 *)ERROR_PTR("pix not defined", procName, NULL);
1769  return pix->data;
1770 }
1771 
1772 
1786 l_int32
1788  l_uint32 *data)
1789 {
1790  PROCNAME("pixSetData");
1791 
1792  if (!pix)
1793  return ERROR_INT("pix not defined", procName, 1);
1794 
1795  pix->data = data;
1796  return 0;
1797 }
1798 
1799 
1816 l_uint32 *
1818 {
1819 l_int32 count, bytes;
1820 l_uint32 *data, *datas;
1821 
1822  PROCNAME("pixExtractData");
1823 
1824  if (!pixs)
1825  return (l_uint32 *)ERROR_PTR("pixs not defined", procName, NULL);
1826 
1827  count = pixGetRefcount(pixs);
1828  if (count == 1) { /* extract */
1829  data = pixGetData(pixs);
1830  pixSetData(pixs, NULL);
1831  } else { /* refcount > 1; copy */
1832  bytes = 4 * pixGetWpl(pixs) * pixGetHeight(pixs);
1833  datas = pixGetData(pixs);
1834  if ((data = (l_uint32 *)pixdata_malloc(bytes)) == NULL)
1835  return (l_uint32 *)ERROR_PTR("data not made", procName, NULL);
1836  memcpy(data, datas, bytes);
1837  }
1838 
1839  return data;
1840 }
1841 
1842 
1857 l_int32
1859 {
1860 l_uint32 *data;
1861 
1862  PROCNAME("pixFreeData");
1863 
1864  if (!pix)
1865  return ERROR_INT("pix not defined", procName, 1);
1866 
1867  if ((data = pixGetData(pix)) != NULL) {
1868  pixdata_free(data);
1869  pix->data = NULL;
1870  }
1871  return 0;
1872 }
1873 
1874 
1875 /*--------------------------------------------------------------------*
1876  * Pix line ptrs *
1877  *--------------------------------------------------------------------*/
1948 void **
1950  l_int32 *psize)
1951 {
1952 l_int32 i, h, wpl;
1953 l_uint32 *data;
1954 void **lines;
1955 
1956  PROCNAME("pixGetLinePtrs");
1957 
1958  if (psize) *psize = 0;
1959  if (!pix)
1960  return (void **)ERROR_PTR("pix not defined", procName, NULL);
1961 
1962  h = pixGetHeight(pix);
1963  if (psize) *psize = h;
1964  if ((lines = (void **)LEPT_CALLOC(h, sizeof(void *))) == NULL)
1965  return (void **)ERROR_PTR("lines not made", procName, NULL);
1966  wpl = pixGetWpl(pix);
1967  data = pixGetData(pix);
1968  for (i = 0; i < h; i++)
1969  lines[i] = (void *)(data + i * wpl);
1970 
1971  return lines;
1972 }
1973 
1974 
1975 /*--------------------------------------------------------------------*
1976  * Pix Size Comparisons *
1977  *--------------------------------------------------------------------*/
1984 l_int32
1985 pixSizesEqual(const PIX *pix1,
1986  const PIX *pix2)
1987 {
1988  PROCNAME("pixSizesEqual");
1989 
1990  if (!pix1 || !pix2)
1991  return ERROR_INT("pix1 and pix2 not both defined", procName, 0);
1992 
1993  if (pix1 == pix2)
1994  return 1;
1995 
1996  if ((pixGetWidth(pix1) != pixGetWidth(pix2)) ||
1997  (pixGetHeight(pix1) != pixGetHeight(pix2)) ||
1998  (pixGetDepth(pix1) != pixGetDepth(pix2)))
1999  return 0;
2000  else
2001  return 1;
2002 }
2003 
2004 
2012 l_ok
2014  l_float32 *pratio)
2015 {
2016 l_int32 w, h;
2017 
2018  PROCNAME("pixMaxAspectRatio");
2019 
2020  if (!pratio)
2021  return ERROR_INT("&ratio not defined", procName, 1);
2022  *pratio = -1.0;
2023  if (!pixs)
2024  return ERROR_INT("pixs not defined", procName, 1);
2025  pixGetDimensions(pixs, &w, &h, NULL);
2026  if (w == 0 || h == 0) {
2027  L_ERROR("invalid size: w = %d, h = %d\n", procName, w, h);
2028  return 1;
2029  }
2030 
2031  *pratio = L_MAX((l_float32)h / (l_float32)w, (l_float32)w / (l_float32)h);
2032  return 0;
2033 }
2034 
2035 
2036 /*--------------------------------------------------------------------*
2037  * Print output for debugging *
2038  *--------------------------------------------------------------------*/
2039 extern const char *ImageFileFormatExtensions[];
2040 
2049 l_ok
2051  const PIX *pix,
2052  const char *text)
2053 {
2054 l_int32 informat;
2055 const PIXCMAP *cmap;
2056 
2057  PROCNAME("pixPrintStreamInfo");
2058 
2059  if (!fp)
2060  return ERROR_INT("fp not defined", procName, 1);
2061  if (!pix)
2062  return ERROR_INT("pix not defined", procName, 1);
2063 
2064  if (text)
2065  fprintf(fp, " Pix Info for %s:\n", text);
2066  fprintf(fp, " width = %d, height = %d, depth = %d, spp = %d\n",
2067  pixGetWidth(pix), pixGetHeight(pix), pixGetDepth(pix),
2068  pixGetSpp(pix));
2069  fprintf(fp, " wpl = %d, data = %p, refcount = %d\n",
2070  pixGetWpl(pix), pix->data, pixGetRefcount(pix));
2071  fprintf(fp, " xres = %d, yres = %d\n", pixGetXRes(pix), pixGetYRes(pix));
2072  if ((cmap = pix->colormap) != NULL)
2073  pixcmapWriteStream(fp, cmap);
2074  else
2075  fprintf(fp, " no colormap\n");
2076  informat = pixGetInputFormat(pix);
2077  fprintf(fp, " input format: %d (%s)\n", informat,
2078  ImageFileFormatExtensions[informat]);
2079  if (pix->text != NULL)
2080  fprintf(fp, " text: %s\n", pix->text);
2081 
2082  return 0;
2083 }
l_ok pixResizeImageData(PIX *pixd, const PIX *pixs)
pixResizeImageData()
Definition: pix1.c:768
l_int32 xres
Definition: pix.h:146
l_uint32 * data
Definition: pix.h:154
l_uint32 w
Definition: pix.h:140
l_int32 pixFreeData(PIX *pix)
pixFreeData()
Definition: pix1.c:1858
PIX * pixCreateTemplate(const PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:383
l_int32 special
Definition: pix.h:151
l_int32 informat
Definition: pix.h:150
l_int32 pixSetData(PIX *pix, l_uint32 *data)
pixSetData()
Definition: pix1.c:1787
l_uint32 refcount
Definition: pix.h:145
l_int32 yres
Definition: pix.h:148
struct PixColormap * colormap
Definition: pix.h:153
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
void ** pixGetLinePtrs(PIX *pix, l_int32 *psize)
pixGetLinePtrs()
Definition: pix1.c:1949
l_uint8 * pixGetTextCompNew(PIX *pix, size_t *psize)
pixGetTextCompNew()
Definition: pix1.c:1617
void(* dealloc_fn)(void *)
Definition: pix.h:1299
l_uint32 * pixExtractData(PIX *pixs)
pixExtractData()
Definition: pix1.c:1817
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
void pixcmapDestroy(PIXCMAP **pcmap)
pixcmapDestroy()
Definition: colormap.c:279
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
l_ok pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
Definition: pix1.c:1699
l_ok pixSetDimensions(PIX *pix, l_int32 w, l_int32 h, l_int32 d)
pixSetDimensions()
Definition: pix1.c:1140
static struct PixMemoryManager pix_mem_manager
Definition: pix1.c:236
l_ok pixSetText(PIX *pix, const char *textstring)
pixSetText()
Definition: pix1.c:1536
PIXCMAP * pixcmapCreate(l_int32 depth)
pixcmapCreate()
Definition: colormap.c:125
l_ok pixGetResolution(const PIX *pix, l_int32 *pxres, l_int32 *pyres)
pixGetResolution()
Definition: pix1.c:1361
l_ok pixDestroyColormap(PIX *pix)
pixDestroyColormap()
Definition: pix1.c:1728
static void pixFree(PIX *pix)
pixFree()
Definition: pix1.c:651
l_uint32 d
Definition: pix.h:142
l_uint32 h
Definition: pix.h:141
char * text
Definition: pix.h:152
PIX * pixCreateTemplateNoInit(const PIX *pixs)
pixCreateTemplateNoInit()
Definition: pix1.c:417
PIX * pixCreateHeader(l_int32 width, l_int32 height, l_int32 depth)
pixCreateHeader()
Definition: pix1.c:504
l_ok pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
Definition: pix2.c:1382
l_ok pixPrintStreamInfo(FILE *fp, const PIX *pix, const char *text)
pixPrintStreamInfo()
Definition: pix1.c:2050
PIX * pixCreateNoInit(l_int32 width, l_int32 height, l_int32 depth)
pixCreateNoInit()
Definition: pix1.c:346
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
l_ok stringReplace(char **pdest, const char *src)
stringReplace()
Definition: utils2.c:345
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixcmapIsValid(const PIXCMAP *cmap, PIX *pix, l_int32 *pvalid)
pixcmapIsValid()
Definition: colormap.c:317
l_ok pixcmapWriteStream(FILE *fp, const PIXCMAP *cmap)
pixcmapWriteStream()
Definition: colormap.c:1965
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
l_ok pixSwapAndDestroy(PIX **ppixd, PIX **ppixs)
pixSwapAndDestroy()
Definition: pix1.c:993
l_ok pixSetTextCompNew(PIX *pix, const l_uint8 *data, size_t size)
pixSetTextCompNew()
Definition: pix1.c:1648
char * pixGetText(PIX *pix)
pixGetText()
Definition: pix1.c:1512
char * stringJoin(const char *src1, const char *src2)
stringJoin()
Definition: utils2.c:518
Definition: pix.h:138
void *(* alloc_fn)(size_t)
Definition: pix.h:1296
l_ok pixCopyColormap(PIX *pixd, const PIX *pixs)
pixCopyColormap()
Definition: pix1.c:816
l_uint32 wpl
Definition: pix.h:144
l_ok pixSetResolution(PIX *pix, l_int32 xres, l_int32 yres)
pixSetResolution()
Definition: pix1.c:1387
PIX * pixCreateWithCmap(l_int32 width, l_int32 height, l_int32 depth, l_int32 initcolor)
pixCreateWithCmap()
Definition: pix1.c:458
l_ok pixCopyDimensions(PIX *pixd, const PIX *pixs)
pixCopyDimensions()
Definition: pix1.c:1164
l_ok pixCopySpp(PIX *pixd, const PIX *pixs)
pixCopySpp()
Definition: pix1.c:1236
PIXCMAP * pixcmapCopy(const PIXCMAP *cmaps)
pixcmapCopy()
Definition: colormap.c:248
l_ok pixTransferAllData(PIX *pixd, PIX **ppixs, l_int32 copytext, l_int32 copyformat)
pixTransferAllData()
Definition: pix1.c:902
l_int32 pixSizesEqual(const PIX *pix1, const PIX *pix2)
pixSizesEqual()
Definition: pix1.c:1985
l_ok pixcmapAddColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval)
pixcmapAddColor()
Definition: colormap.c:414
void setPixMemoryManager(alloc_fn allocator, dealloc_fn deallocator)
setPixMemoryManager()
Definition: pix1.c:296
l_ok pixAddText(PIX *pix, const char *textstring)
pixAddText()
Definition: pix1.c:1564
l_uint32 spp
Definition: pix.h:143
l_ok pixMaxAspectRatio(PIX *pixs, l_float32 *pratio)
pixMaxAspectRatio()
Definition: pix1.c:2013