Leptonica  1.77.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 
192 #include <string.h>
193 #include "allheaders.h"
194 
195 static void pixFree(PIX *pix);
196 
197 
198 /*-------------------------------------------------------------------------*
199  * Pix Memory Management *
200  * *
201  * These functions give you the freedom to specify at compile or run *
202  * time the allocator and deallocator to be used for pix. It has no *
203  * effect on memory management for other data structs, which are *
204  * controlled by the #defines in environ.h. Likewise, the #defines *
205  * in environ.h have no effect on the pix memory management. *
206  * The default functions are malloc and free. Use setPixMemoryManager() *
207  * to specify other functions to use. *
208  *-------------------------------------------------------------------------*/
209 
211  /*
212  * <pre>
213  * Notes:
214  * (1) The allocator and deallocator function types,
215  * alloc_fn and dealloc_fn, are defined in pix.h.
216  * </pre>
217  */
219 {
220  alloc_fn allocator;
221  dealloc_fn deallocator;
222 };
223 
226  &malloc,
227  &free
228 };
229 
230 static void *
231 pix_malloc(size_t size)
232 {
233 #ifndef _MSC_VER
234  return (*pix_mem_manager.allocator)(size);
235 #else /* _MSC_VER */
236  /* Under MSVC++, pix_mem_manager is initialized after a call
237  * to pix_malloc. Just ignore the custom allocator feature. */
238  return malloc(size);
239 #endif /* _MSC_VER */
240 }
241 
242 static void
243 pix_free(void *ptr)
244 {
245 #ifndef _MSC_VER
246  (*pix_mem_manager.deallocator)(ptr);
247  return;
248 #else /* _MSC_VER */
249  /* Under MSVC++, pix_mem_manager is initialized after a call
250  * to pix_malloc. Just ignore the custom allocator feature. */
251  free(ptr);
252  return;
253 #endif /* _MSC_VER */
254 }
255 
281 void
283  dealloc_fn deallocator)
284 {
285  if (allocator) pix_mem_manager.allocator = allocator;
286  if (deallocator) pix_mem_manager.deallocator = deallocator;
287  return;
288 }
289 
290 
291 /*--------------------------------------------------------------------*
292  * Pix Creation *
293  *--------------------------------------------------------------------*/
301 PIX *
302 pixCreate(l_int32 width,
303  l_int32 height,
304  l_int32 depth)
305 {
306 PIX *pixd;
307 
308  PROCNAME("pixCreate");
309 
310  if ((pixd = pixCreateNoInit(width, height, depth)) == NULL)
311  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
312  memset(pixd->data, 0, 4LL * pixd->wpl * pixd->h);
313  return pixd;
314 }
315 
316 
330 PIX *
331 pixCreateNoInit(l_int32 width,
332  l_int32 height,
333  l_int32 depth)
334 {
335 l_int32 wpl;
336 PIX *pixd;
337 l_uint32 *data;
338 
339  PROCNAME("pixCreateNoInit");
340  if ((pixd = pixCreateHeader(width, height, depth)) == NULL)
341  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
342  wpl = pixGetWpl(pixd);
343  if ((data = (l_uint32 *)pix_malloc(4LL * wpl * height)) == NULL) {
344  pixDestroy(&pixd);
345  return (PIX *)ERROR_PTR("pix_malloc fail for data", procName, NULL);
346  }
347  pixSetData(pixd, data);
348  pixSetPadBits(pixd, 0);
349  return pixd;
350 }
351 
352 
366 PIX *
368 {
369 PIX *pixd;
370 
371  PROCNAME("pixCreateTemplate");
372 
373  if (!pixs)
374  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
375 
376  if ((pixd = pixCreateTemplateNoInit(pixs)) == NULL)
377  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
378  memset(pixd->data, 0, 4LL * pixd->wpl * pixd->h);
379  return pixd;
380 }
381 
382 
396 PIX *
398 {
399 l_int32 w, h, d;
400 PIX *pixd;
401 
402  PROCNAME("pixCreateTemplateNoInit");
403 
404  if (!pixs)
405  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
406 
407  pixGetDimensions(pixs, &w, &h, &d);
408  if ((pixd = pixCreateNoInit(w, h, d)) == NULL)
409  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
410  pixCopySpp(pixd, pixs);
411  pixCopyResolution(pixd, pixs);
412  pixCopyColormap(pixd, pixs);
413  pixCopyText(pixd, pixs);
414  pixCopyInputFormat(pixd, pixs);
415  return pixd;
416 }
417 
418 
439 PIX *
440 pixCreateHeader(l_int32 width,
441  l_int32 height,
442  l_int32 depth)
443 {
444 l_int32 wpl;
445 l_uint64 wpl64, bignum;
446 PIX *pixd;
447 
448  PROCNAME("pixCreateHeader");
449 
450  if ((depth != 1) && (depth != 2) && (depth != 4) && (depth != 8)
451  && (depth != 16) && (depth != 24) && (depth != 32))
452  return (PIX *)ERROR_PTR("depth must be {1, 2, 4, 8, 16, 24, 32}",
453  procName, NULL);
454  if (width <= 0)
455  return (PIX *)ERROR_PTR("width must be > 0", procName, NULL);
456  if (height <= 0)
457  return (PIX *)ERROR_PTR("height must be > 0", procName, NULL);
458 
459  /* Avoid overflow in malloc, malicious or otherwise */
460  wpl64 = ((l_uint64)width * (l_uint64)depth + 31) / 32;
461  if (wpl64 > ((1LL << 29) - 1)) {
462  L_ERROR("requested w = %d, h = %d, d = %d\n",
463  procName, width, height, depth);
464  return (PIX *)ERROR_PTR("wpl >= 2^29", procName, NULL);
465  }
466  wpl = (l_int32)wpl64;
467  bignum = 4LL * wpl * height; /* number of bytes to be requested */
468  if (bignum > ((1LL << 31) - 1)) {
469  L_ERROR("requested w = %d, h = %d, d = %d\n",
470  procName, width, height, depth);
471  return (PIX *)ERROR_PTR("requested bytes >= 2^31", procName, NULL);
472  }
473 
474  if ((pixd = (PIX *)LEPT_CALLOC(1, sizeof(PIX))) == NULL)
475  return (PIX *)ERROR_PTR("LEPT_CALLOC fail for pixd", procName, NULL);
476  pixSetWidth(pixd, width);
477  pixSetHeight(pixd, height);
478  pixSetDepth(pixd, depth);
479  pixSetWpl(pixd, wpl);
480  if (depth == 24 || depth == 32)
481  pixSetSpp(pixd, 3);
482  else
483  pixSetSpp(pixd, 1);
484  pixd->refcount = 1;
485  pixd->informat = IFF_UNKNOWN;
486  return pixd;
487 }
488 
489 
514 PIX *
515 pixClone(PIX *pixs)
516 {
517  PROCNAME("pixClone");
518 
519  if (!pixs)
520  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
521  pixChangeRefcount(pixs, 1);
522 
523  return pixs;
524 }
525 
526 
527 /*--------------------------------------------------------------------*
528  * Pix Destruction *
529  *--------------------------------------------------------------------*/
542 void
544 {
545 PIX *pix;
546 
547  PROCNAME("pixDestroy");
548 
549  if (!ppix) {
550  L_WARNING("ptr address is null!\n", procName);
551  return;
552  }
553 
554  if ((pix = *ppix) == NULL)
555  return;
556  pixFree(pix);
557  *ppix = NULL;
558  return;
559 }
560 
561 
573 static void
575 {
576 l_uint32 *data;
577 char *text;
578 
579  if (!pix) return;
580 
581  pixChangeRefcount(pix, -1);
582  if (pixGetRefcount(pix) <= 0) {
583  if ((data = pixGetData(pix)) != NULL)
584  pix_free(data);
585  if ((text = pixGetText(pix)) != NULL)
586  LEPT_FREE(text);
587  pixDestroyColormap(pix);
588  LEPT_FREE(pix);
589  }
590  return;
591 }
592 
593 
594 /*-------------------------------------------------------------------------*
595  * Pix Copy *
596  *-------------------------------------------------------------------------*/
627 PIX *
628 pixCopy(PIX *pixd, /* can be null */
629  PIX *pixs)
630 {
631 l_int32 bytes;
632 l_uint32 *datas, *datad;
633 
634  PROCNAME("pixCopy");
635 
636  if (!pixs)
637  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
638  if (pixs == pixd)
639  return pixd;
640 
641  /* Total bytes in image data */
642  bytes = 4 * pixGetWpl(pixs) * pixGetHeight(pixs);
643 
644  /* If we're making a new pix ... */
645  if (!pixd) {
646  if ((pixd = pixCreateTemplate(pixs)) == NULL)
647  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
648  datas = pixGetData(pixs);
649  datad = pixGetData(pixd);
650  memcpy(datad, datas, bytes);
651  return pixd;
652  }
653 
654  /* Reallocate image data if sizes are different. If this fails,
655  * pixd hasn't been changed. But we want to signal that the copy
656  * failed, so return NULL. This will cause a memory leak if the
657  * return ptr is assigned to pixd, but that is preferred to proceeding
658  * with an incorrect pixd, and in any event this use case of
659  * pixCopy() -- reallocating into an existing pix -- is infrequent. */
660  if (pixResizeImageData(pixd, pixs) == 1)
661  return (PIX *)ERROR_PTR("reallocation of data failed", procName, NULL);
662 
663  /* Copy non-image data fields */
664  pixCopyColormap(pixd, pixs);
665  pixCopySpp(pixd, pixs);
666  pixCopyResolution(pixd, pixs);
667  pixCopyInputFormat(pixd, pixs);
668  pixCopyText(pixd, pixs);
669 
670  /* Copy image data */
671  datas = pixGetData(pixs);
672  datad = pixGetData(pixd);
673  memcpy(datad, datas, bytes);
674  return pixd;
675 }
676 
677 
695 l_ok
697  const PIX *pixs)
698 {
699 l_int32 w, h, d, wpl, bytes;
700 l_uint32 *data;
701 
702  PROCNAME("pixResizeImageData");
703 
704  if (!pixs)
705  return ERROR_INT("pixs not defined", procName, 1);
706  if (!pixd)
707  return ERROR_INT("pixd not defined", procName, 1);
708 
709  if (pixSizesEqual(pixs, pixd)) /* nothing to do */
710  return 0;
711 
712  /* Make sure we can copy the data */
713  pixGetDimensions(pixs, &w, &h, &d);
714  wpl = pixGetWpl(pixs);
715  bytes = 4 * wpl * h;
716  if ((data = (l_uint32 *)pix_malloc(bytes)) == NULL)
717  return ERROR_INT("pix_malloc fail for data", procName, 1);
718 
719  /* OK, do it */
720  pixSetWidth(pixd, w);
721  pixSetHeight(pixd, h);
722  pixSetDepth(pixd, d);
723  pixSetWpl(pixd, wpl);
724  pixFreeData(pixd); /* free any existing image data */
725  pixSetData(pixd, data); /* set the uninitialized memory buffer */
726  pixCopyResolution(pixd, pixs);
727  return 0;
728 }
729 
730 
744 l_ok
746  PIX *pixs)
747 {
748 l_int32 valid;
749 PIXCMAP *cmaps, *cmapd;
750 
751  PROCNAME("pixCopyColormap");
752 
753  if (!pixs)
754  return ERROR_INT("pixs not defined", procName, 1);
755  if (!pixd)
756  return ERROR_INT("pixd not defined", procName, 1);
757  if (pixs == pixd)
758  return 0; /* no-op */
759 
760  pixDestroyColormap(pixd);
761  if ((cmaps = pixGetColormap(pixs)) == NULL) /* not an error */
762  return 0;
763  pixcmapIsValid(cmaps, &valid);
764  if (!valid)
765  return ERROR_INT("cmap not valid", procName, 1);
766 
767  if ((cmapd = pixcmapCopy(cmaps)) == NULL)
768  return ERROR_INT("cmapd not made", procName, 1);
769  pixSetColormap(pixd, cmapd);
770  return 0;
771 }
772 
773 
780 l_int32
781 pixSizesEqual(const PIX *pix1,
782  const PIX *pix2)
783 {
784  PROCNAME("pixSizesEqual");
785 
786  if (!pix1 || !pix2)
787  return ERROR_INT("pix1 and pix2 not both defined", procName, 0);
788 
789  if (pix1 == pix2)
790  return 1;
791 
792  if ((pixGetWidth(pix1) != pixGetWidth(pix2)) ||
793  (pixGetHeight(pix1) != pixGetHeight(pix2)) ||
794  (pixGetDepth(pix1) != pixGetDepth(pix2)))
795  return 0;
796  else
797  return 1;
798 }
799 
800 
854 l_ok
856  PIX **ppixs,
857  l_int32 copytext,
858  l_int32 copyformat)
859 {
860 l_int32 nbytes;
861 PIX *pixs;
862 
863  PROCNAME("pixTransferAllData");
864 
865  if (!ppixs)
866  return ERROR_INT("&pixs not defined", procName, 1);
867  if ((pixs = *ppixs) == NULL)
868  return ERROR_INT("pixs not defined", procName, 1);
869  if (!pixd)
870  return ERROR_INT("pixd not defined", procName, 1);
871  if (pixs == pixd) /* no-op */
872  return ERROR_INT("pixd == pixs", procName, 1);
873 
874  if (pixGetRefcount(pixs) == 1) { /* transfer the data, cmap, text */
875  pixFreeData(pixd); /* dealloc any existing data */
876  pixSetData(pixd, pixGetData(pixs)); /* transfer new data from pixs */
877  pixs->data = NULL; /* pixs no longer owns data */
878  pixSetColormap(pixd, pixGetColormap(pixs)); /* frees old; sets new */
879  pixs->colormap = NULL; /* pixs no longer owns colormap */
880  if (copytext) {
881  pixSetText(pixd, pixGetText(pixs));
882  pixSetText(pixs, NULL);
883  }
884  } else { /* preserve pixs by making a copy of the data, cmap, text */
885  pixResizeImageData(pixd, pixs);
886  nbytes = 4 * pixGetWpl(pixs) * pixGetHeight(pixs);
887  memcpy(pixGetData(pixd), pixGetData(pixs), nbytes);
888  pixCopyColormap(pixd, pixs);
889  if (copytext)
890  pixCopyText(pixd, pixs);
891  }
892 
893  pixCopySpp(pixd, pixs);
894  pixCopyResolution(pixd, pixs);
895  pixCopyDimensions(pixd, pixs);
896  if (copyformat)
897  pixCopyInputFormat(pixd, pixs);
898 
899  /* This will destroy pixs if data was transferred;
900  * otherwise, it just decrements its refcount. */
901  pixDestroy(ppixs);
902  return 0;
903 }
904 
905 
944 l_ok
946  PIX **ppixs)
947 {
948  PROCNAME("pixSwapAndDestroy");
949 
950  if (!ppixd)
951  return ERROR_INT("&pixd not defined", procName, 1);
952  if (!ppixs)
953  return ERROR_INT("&pixs not defined", procName, 1);
954  if (*ppixs == NULL)
955  return ERROR_INT("pixs not defined", procName, 1);
956  if (ppixs == ppixd) /* no-op */
957  return ERROR_INT("&pixd == &pixs", procName, 1);
958 
959  pixDestroy(ppixd);
960  *ppixd = pixClone(*ppixs);
961  pixDestroy(ppixs);
962  return 0;
963 }
964 
965 
966 /*--------------------------------------------------------------------*
967  * Accessors *
968  *--------------------------------------------------------------------*/
969 l_int32
970 pixGetWidth(const PIX *pix)
971 {
972  PROCNAME("pixGetWidth");
973 
974  if (!pix)
975  return ERROR_INT("pix not defined", procName, 0);
976 
977  return pix->w;
978 }
979 
980 
981 l_int32
982 pixSetWidth(PIX *pix,
983  l_int32 width)
984 {
985  PROCNAME("pixSetWidth");
986 
987  if (!pix)
988  return ERROR_INT("pix not defined", procName, 1);
989  if (width < 0) {
990  pix->w = 0;
991  return ERROR_INT("width must be >= 0", procName, 1);
992  }
993 
994  pix->w = width;
995  return 0;
996 }
997 
998 
999 l_int32
1000 pixGetHeight(const PIX *pix)
1001 {
1002  PROCNAME("pixGetHeight");
1003 
1004  if (!pix)
1005  return ERROR_INT("pix not defined", procName, 0);
1006 
1007  return pix->h;
1008 }
1009 
1010 
1011 l_int32
1012 pixSetHeight(PIX *pix,
1013  l_int32 height)
1014 {
1015  PROCNAME("pixSetHeight");
1016 
1017  if (!pix)
1018  return ERROR_INT("pix not defined", procName, 1);
1019  if (height < 0) {
1020  pix->h = 0;
1021  return ERROR_INT("h must be >= 0", procName, 1);
1022  }
1023 
1024  pix->h = height;
1025  return 0;
1026 }
1027 
1028 
1029 l_int32
1030 pixGetDepth(const PIX *pix)
1031 {
1032  PROCNAME("pixGetDepth");
1033 
1034  if (!pix)
1035  return ERROR_INT("pix not defined", procName, 0);
1036 
1037  return pix->d;
1038 }
1039 
1040 
1041 l_int32
1042 pixSetDepth(PIX *pix,
1043  l_int32 depth)
1044 {
1045  PROCNAME("pixSetDepth");
1046 
1047  if (!pix)
1048  return ERROR_INT("pix not defined", procName, 1);
1049  if (depth < 1)
1050  return ERROR_INT("d must be >= 1", procName, 1);
1051 
1052  pix->d = depth;
1053  return 0;
1054 }
1055 
1056 
1064 l_ok
1066  l_int32 *pw,
1067  l_int32 *ph,
1068  l_int32 *pd)
1069 {
1070  PROCNAME("pixGetDimensions");
1071 
1072  if (pw) *pw = 0;
1073  if (ph) *ph = 0;
1074  if (pd) *pd = 0;
1075  if (!pix)
1076  return ERROR_INT("pix not defined", procName, 1);
1077  if (pw) *pw = pix->w;
1078  if (ph) *ph = pix->h;
1079  if (pd) *pd = pix->d;
1080  return 0;
1081 }
1082 
1083 
1091 l_ok
1093  l_int32 w,
1094  l_int32 h,
1095  l_int32 d)
1096 {
1097  PROCNAME("pixSetDimensions");
1098 
1099  if (!pix)
1100  return ERROR_INT("pix not defined", procName, 1);
1101  if (w > 0) pixSetWidth(pix, w);
1102  if (h > 0) pixSetHeight(pix, h);
1103  if (d > 0) pixSetDepth(pix, d);
1104  return 0;
1105 }
1106 
1107 
1115 l_ok
1117  const PIX *pixs)
1118 {
1119  PROCNAME("pixCopyDimensions");
1120 
1121  if (!pixd)
1122  return ERROR_INT("pixd not defined", procName, 1);
1123  if (!pixs)
1124  return ERROR_INT("pixs not defined", procName, 1);
1125  if (pixs == pixd)
1126  return 0; /* no-op */
1127 
1128  pixSetWidth(pixd, pixGetWidth(pixs));
1129  pixSetHeight(pixd, pixGetHeight(pixs));
1130  pixSetDepth(pixd, pixGetDepth(pixs));
1131  pixSetWpl(pixd, pixGetWpl(pixs));
1132  return 0;
1133 }
1134 
1135 
1136 l_int32
1137 pixGetSpp(const PIX *pix)
1138 {
1139  PROCNAME("pixGetSpp");
1140 
1141  if (!pix)
1142  return ERROR_INT("pix not defined", procName, 0);
1143 
1144  return pix->spp;
1145 }
1146 
1147 
1148 /*
1149  * \brief pixSetSpp()
1150  *
1151  * \param[in] pix
1152  * \param[in] spp 1, 3 or 4 samples
1153  * \return 0 if OK, 1 on error
1154  *
1155  * <pre>
1156  * Notes:
1157  * (1) For a 32 bpp pix, this can be used to ignore the
1158  * alpha sample (spp == 3) or to use it (spp == 4).
1159  * For example, to write a spp == 4 image without the alpha
1160  * sample (as an rgb pix), call pixSetSpp(pix, 3) and
1161  * then write it out as a png.
1162  * </pre>
1163  */
1164 l_int32
1165 pixSetSpp(PIX *pix,
1166  l_int32 spp)
1167 {
1168  PROCNAME("pixSetSpp");
1169 
1170  if (!pix)
1171  return ERROR_INT("pix not defined", procName, 1);
1172  if (spp < 1)
1173  return ERROR_INT("spp must be >= 1", procName, 1);
1174 
1175  pix->spp = spp;
1176  return 0;
1177 }
1178 
1179 
1187 l_ok
1189  const PIX *pixs)
1190 {
1191  PROCNAME("pixCopySpp");
1192 
1193  if (!pixd)
1194  return ERROR_INT("pixd not defined", procName, 1);
1195  if (!pixs)
1196  return ERROR_INT("pixs not defined", procName, 1);
1197  if (pixs == pixd)
1198  return 0; /* no-op */
1199 
1200  pixSetSpp(pixd, pixGetSpp(pixs));
1201  return 0;
1202 }
1203 
1204 
1205 l_int32
1206 pixGetWpl(const PIX *pix)
1207 {
1208  PROCNAME("pixGetWpl");
1209 
1210  if (!pix)
1211  return ERROR_INT("pix not defined", procName, 0);
1212  return pix->wpl;
1213 }
1214 
1215 
1216 l_int32
1217 pixSetWpl(PIX *pix,
1218  l_int32 wpl)
1219 {
1220  PROCNAME("pixSetWpl");
1221 
1222  if (!pix)
1223  return ERROR_INT("pix not defined", procName, 1);
1224 
1225  pix->wpl = wpl;
1226  return 0;
1227 }
1228 
1229 
1230 l_int32
1231 pixGetRefcount(const PIX *pix)
1232 {
1233  PROCNAME("pixGetRefcount");
1234 
1235  if (!pix)
1236  return ERROR_INT("pix not defined", procName, 0);
1237  return pix->refcount;
1238 }
1239 
1240 
1241 l_int32
1242 pixChangeRefcount(PIX *pix,
1243  l_int32 delta)
1244 {
1245  PROCNAME("pixChangeRefcount");
1246 
1247  if (!pix)
1248  return ERROR_INT("pix not defined", procName, 1);
1249 
1250  pix->refcount += delta;
1251  return 0;
1252 }
1253 
1254 
1255 l_int32
1256 pixGetXRes(const PIX *pix)
1257 {
1258  PROCNAME("pixGetXRes");
1259 
1260  if (!pix)
1261  return ERROR_INT("pix not defined", procName, 0);
1262  return pix->xres;
1263 }
1264 
1265 
1266 l_int32
1267 pixSetXRes(PIX *pix,
1268  l_int32 res)
1269 {
1270  PROCNAME("pixSetXRes");
1271 
1272  if (!pix)
1273  return ERROR_INT("pix not defined", procName, 1);
1274 
1275  pix->xres = res;
1276  return 0;
1277 }
1278 
1279 
1280 l_int32
1281 pixGetYRes(const PIX *pix)
1282 {
1283  PROCNAME("pixGetYRes");
1284 
1285  if (!pix)
1286  return ERROR_INT("pix not defined", procName, 0);
1287  return pix->yres;
1288 }
1289 
1290 
1291 l_int32
1292 pixSetYRes(PIX *pix,
1293  l_int32 res)
1294 {
1295  PROCNAME("pixSetYRes");
1296 
1297  if (!pix)
1298  return ERROR_INT("pix not defined", procName, 1);
1299 
1300  pix->yres = res;
1301  return 0;
1302 }
1303 
1304 
1312 l_ok
1314  l_int32 *pxres,
1315  l_int32 *pyres)
1316 {
1317  PROCNAME("pixGetResolution");
1318 
1319  if (pxres) *pxres = 0;
1320  if (pyres) *pyres = 0;
1321  if (!pxres && !pyres)
1322  return ERROR_INT("no output requested", procName, 1);
1323  if (!pix)
1324  return ERROR_INT("pix not defined", procName, 1);
1325  if (pxres) *pxres = pix->xres;
1326  if (pyres) *pyres = pix->yres;
1327  return 0;
1328 }
1329 
1330 
1338 l_ok
1340  l_int32 xres,
1341  l_int32 yres)
1342 {
1343  PROCNAME("pixSetResolution");
1344 
1345  if (!pix)
1346  return ERROR_INT("pix not defined", procName, 1);
1347  if (xres > 0) pix->xres = xres;
1348  if (yres > 0) pix->yres = yres;
1349  return 0;
1350 }
1351 
1352 
1353 l_int32
1354 pixCopyResolution(PIX *pixd,
1355  const PIX *pixs)
1356 {
1357  PROCNAME("pixCopyResolution");
1358 
1359  if (!pixs)
1360  return ERROR_INT("pixs not defined", procName, 1);
1361  if (!pixd)
1362  return ERROR_INT("pixd not defined", procName, 1);
1363  if (pixs == pixd)
1364  return 0; /* no-op */
1365 
1366  pixSetXRes(pixd, pixGetXRes(pixs));
1367  pixSetYRes(pixd, pixGetYRes(pixs));
1368  return 0;
1369 }
1370 
1371 
1372 l_int32
1373 pixScaleResolution(PIX *pix,
1374  l_float32 xscale,
1375  l_float32 yscale)
1376 {
1377  PROCNAME("pixScaleResolution");
1378 
1379  if (!pix)
1380  return ERROR_INT("pix not defined", procName, 1);
1381 
1382  if (pix->xres != 0 && pix->yres != 0) {
1383  pix->xres = (l_uint32)(xscale * (l_float32)(pix->xres) + 0.5);
1384  pix->yres = (l_uint32)(yscale * (l_float32)(pix->yres) + 0.5);
1385  }
1386  return 0;
1387 }
1388 
1389 
1390 l_int32
1391 pixGetInputFormat(const PIX *pix)
1392 {
1393  PROCNAME("pixGetInputFormat");
1394 
1395  if (!pix)
1396  return ERROR_INT("pix not defined", procName, 0);
1397  return pix->informat;
1398 }
1399 
1400 
1401 l_int32
1402 pixSetInputFormat(PIX *pix,
1403  l_int32 informat)
1404 {
1405  PROCNAME("pixSetInputFormat");
1406 
1407  if (!pix)
1408  return ERROR_INT("pix not defined", procName, 1);
1409  pix->informat = informat;
1410  return 0;
1411 }
1412 
1413 
1414 l_int32
1415 pixCopyInputFormat(PIX *pixd,
1416  const PIX *pixs)
1417 {
1418  PROCNAME("pixCopyInputFormat");
1419 
1420  if (!pixs)
1421  return ERROR_INT("pixs not defined", procName, 1);
1422  if (!pixd)
1423  return ERROR_INT("pixd not defined", procName, 1);
1424  if (pixs == pixd)
1425  return 0; /* no-op */
1426 
1427  pixSetInputFormat(pixd, pixGetInputFormat(pixs));
1428  return 0;
1429 }
1430 
1431 
1432 l_int32
1433 pixSetSpecial(PIX *pix,
1434  l_int32 special)
1435 {
1436  PROCNAME("pixSetSpecial");
1437 
1438  if (!pix)
1439  return ERROR_INT("pix not defined", procName, 1);
1440  pix->special = special;
1441  return 0;
1442 }
1443 
1444 
1458 char *
1460 {
1461  PROCNAME("pixGetText");
1462 
1463  if (!pix)
1464  return (char *)ERROR_PTR("pix not defined", procName, NULL);
1465  return pix->text;
1466 }
1467 
1468 
1482 l_ok
1484  const char *textstring)
1485 {
1486  PROCNAME("pixSetText");
1487 
1488  if (!pix)
1489  return ERROR_INT("pix not defined", procName, 1);
1490 
1491  stringReplace(&pix->text, textstring);
1492  return 0;
1493 }
1494 
1495 
1510 l_ok
1512  const char *textstring)
1513 {
1514 char *newstring;
1515 
1516  PROCNAME("pixAddText");
1517 
1518  if (!pix)
1519  return ERROR_INT("pix not defined", procName, 1);
1520 
1521  newstring = stringJoin(pixGetText(pix), textstring);
1522  stringReplace(&pix->text, newstring);
1523  LEPT_FREE(newstring);
1524  return 0;
1525 }
1526 
1527 
1528 l_int32
1529 pixCopyText(PIX *pixd,
1530  PIX *pixs)
1531 {
1532  PROCNAME("pixCopyText");
1533 
1534  if (!pixs)
1535  return ERROR_INT("pixs not defined", procName, 1);
1536  if (!pixd)
1537  return ERROR_INT("pixd not defined", procName, 1);
1538  if (pixs == pixd)
1539  return 0; /* no-op */
1540 
1541  pixSetText(pixd, pixGetText(pixs));
1542  return 0;
1543 }
1544 
1545 
1546 PIXCMAP *
1547 pixGetColormap(PIX *pix)
1548 {
1549  PROCNAME("pixGetColormap");
1550 
1551  if (!pix)
1552  return (PIXCMAP *)ERROR_PTR("pix not defined", procName, NULL);
1553  return pix->colormap;
1554 }
1555 
1556 
1572 l_ok
1574  PIXCMAP *colormap)
1575 {
1576  PROCNAME("pixSetColormap");
1577 
1578  if (!pix)
1579  return ERROR_INT("pix not defined", procName, 1);
1580 
1581  pixDestroyColormap(pix);
1582  pix->colormap = colormap;
1583  return 0;
1584 }
1585 
1586 
1593 l_ok
1595 {
1596 PIXCMAP *cmap;
1597 
1598  PROCNAME("pixDestroyColormap");
1599 
1600  if (!pix)
1601  return ERROR_INT("pix not defined", procName, 1);
1602 
1603  if ((cmap = pix->colormap) != NULL) {
1604  pixcmapDestroy(&cmap);
1605  pix->colormap = NULL;
1606  }
1607  return 0;
1608 }
1609 
1610 
1623 l_uint32 *
1625 {
1626  PROCNAME("pixGetData");
1627 
1628  if (!pix)
1629  return (l_uint32 *)ERROR_PTR("pix not defined", procName, NULL);
1630  return pix->data;
1631 }
1632 
1633 
1647 l_int32
1649  l_uint32 *data)
1650 {
1651  PROCNAME("pixSetData");
1652 
1653  if (!pix)
1654  return ERROR_INT("pix not defined", procName, 1);
1655 
1656  pix->data = data;
1657  return 0;
1658 }
1659 
1660 
1677 l_uint32 *
1679 {
1680 l_int32 count, bytes;
1681 l_uint32 *data, *datas;
1682 
1683  PROCNAME("pixExtractData");
1684 
1685  if (!pixs)
1686  return (l_uint32 *)ERROR_PTR("pixs not defined", procName, NULL);
1687 
1688  count = pixGetRefcount(pixs);
1689  if (count == 1) { /* extract */
1690  data = pixGetData(pixs);
1691  pixSetData(pixs, NULL);
1692  } else { /* refcount > 1; copy */
1693  bytes = 4 * pixGetWpl(pixs) * pixGetHeight(pixs);
1694  datas = pixGetData(pixs);
1695  if ((data = (l_uint32 *)pix_malloc(bytes)) == NULL)
1696  return (l_uint32 *)ERROR_PTR("data not made", procName, NULL);
1697  memcpy(data, datas, bytes);
1698  }
1699 
1700  return data;
1701 }
1702 
1703 
1718 l_int32
1720 {
1721 l_uint32 *data;
1722 
1723  PROCNAME("pixFreeData");
1724 
1725  if (!pix)
1726  return ERROR_INT("pix not defined", procName, 1);
1727 
1728  if ((data = pixGetData(pix)) != NULL) {
1729  pix_free(data);
1730  pix->data = NULL;
1731  }
1732  return 0;
1733 }
1734 
1735 
1736 /*--------------------------------------------------------------------*
1737  * Pix line ptrs *
1738  *--------------------------------------------------------------------*/
1809 void **
1811  l_int32 *psize)
1812 {
1813 l_int32 i, h, wpl;
1814 l_uint32 *data;
1815 void **lines;
1816 
1817  PROCNAME("pixGetLinePtrs");
1818 
1819  if (psize) *psize = 0;
1820  if (!pix)
1821  return (void **)ERROR_PTR("pix not defined", procName, NULL);
1822 
1823  h = pixGetHeight(pix);
1824  if (psize) *psize = h;
1825  if ((lines = (void **)LEPT_CALLOC(h, sizeof(void *))) == NULL)
1826  return (void **)ERROR_PTR("lines not made", procName, NULL);
1827  wpl = pixGetWpl(pix);
1828  data = pixGetData(pix);
1829  for (i = 0; i < h; i++)
1830  lines[i] = (void *)(data + i * wpl);
1831 
1832  return lines;
1833 }
1834 
1835 
1836 /*--------------------------------------------------------------------*
1837  * Print output for debugging *
1838  *--------------------------------------------------------------------*/
1839 extern const char *ImageFileFormatExtensions[];
1840 
1849 l_ok
1851  PIX *pix,
1852  const char *text)
1853 {
1854 char *textdata;
1855 l_int32 informat;
1856 PIXCMAP *cmap;
1857 
1858  PROCNAME("pixPrintStreamInfo");
1859 
1860  if (!fp)
1861  return ERROR_INT("fp not defined", procName, 1);
1862  if (!pix)
1863  return ERROR_INT("pix not defined", procName, 1);
1864 
1865  if (text)
1866  fprintf(fp, " Pix Info for %s:\n", text);
1867  fprintf(fp, " width = %d, height = %d, depth = %d, spp = %d\n",
1868  pixGetWidth(pix), pixGetHeight(pix), pixGetDepth(pix),
1869  pixGetSpp(pix));
1870  fprintf(fp, " wpl = %d, data = %p, refcount = %d\n",
1871  pixGetWpl(pix), pixGetData(pix), pixGetRefcount(pix));
1872  fprintf(fp, " xres = %d, yres = %d\n", pixGetXRes(pix), pixGetYRes(pix));
1873  if ((cmap = pixGetColormap(pix)) != NULL)
1874  pixcmapWriteStream(fp, cmap);
1875  else
1876  fprintf(fp, " no colormap\n");
1877  informat = pixGetInputFormat(pix);
1878  fprintf(fp, " input format: %d (%s)\n", informat,
1879  ImageFileFormatExtensions[informat]);
1880  if ((textdata = pixGetText(pix)) != NULL)
1881  fprintf(fp, " text: %s\n", textdata);
1882 
1883  return 0;
1884 }
l_ok pixResizeImageData(PIX *pixd, const PIX *pixs)
pixResizeImageData()
Definition: pix1.c:696
l_int32 xres
Definition: pix.h:142
l_uint32 * data
Definition: pix.h:150
l_uint32 w
Definition: pix.h:136
l_int32 pixFreeData(PIX *pix)
pixFreeData()
Definition: pix1.c:1719
l_int32 special
Definition: pix.h:147
l_int32 informat
Definition: pix.h:146
l_int32 pixSetData(PIX *pix, l_uint32 *data)
pixSetData()
Definition: pix1.c:1648
l_uint32 refcount
Definition: pix.h:141
l_int32 yres
Definition: pix.h:144
struct PixColormap * colormap
Definition: pix.h:149
void ** pixGetLinePtrs(PIX *pix, l_int32 *psize)
pixGetLinePtrs()
Definition: pix1.c:1810
l_ok pixcmapWriteStream(FILE *fp, PIXCMAP *cmap)
pixcmapWriteStream()
Definition: colormap.c:1758
void(* dealloc_fn)(void *)
Definition: pix.h:1339
l_uint32 * pixExtractData(PIX *pixs)
pixExtractData()
Definition: pix1.c:1678
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:302
void pixcmapDestroy(PIXCMAP **pcmap)
pixcmapDestroy()
Definition: colormap.c:265
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1624
PIX * pixCreateTemplate(PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:367
l_ok pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
Definition: pix1.c:1573
PIX * pixCreateTemplateNoInit(PIX *pixs)
pixCreateTemplateNoInit()
Definition: pix1.c:397
l_ok pixSetDimensions(PIX *pix, l_int32 w, l_int32 h, l_int32 d)
pixSetDimensions()
Definition: pix1.c:1092
static struct PixMemoryManager pix_mem_manager
Definition: pix1.c:225
l_ok pixSetText(PIX *pix, const char *textstring)
pixSetText()
Definition: pix1.c:1483
l_ok pixGetResolution(const PIX *pix, l_int32 *pxres, l_int32 *pyres)
pixGetResolution()
Definition: pix1.c:1313
l_ok pixDestroyColormap(PIX *pix)
pixDestroyColormap()
Definition: pix1.c:1594
static void pixFree(PIX *pix)
pixFree()
Definition: pix1.c:574
l_uint32 d
Definition: pix.h:138
l_uint32 h
Definition: pix.h:137
char * text
Definition: pix.h:148
l_ok pixcmapIsValid(PIXCMAP *cmap, l_int32 *pvalid)
pixcmapIsValid()
Definition: colormap.c:293
PIX * pixCreateHeader(l_int32 width, l_int32 height, l_int32 depth)
pixCreateHeader()
Definition: pix1.c:440
l_ok pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
Definition: pix2.c:1307
PIX * pixCreateNoInit(l_int32 width, l_int32 height, l_int32 depth)
pixCreateNoInit()
Definition: pix1.c:331
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:515
l_ok stringReplace(char **pdest, const char *src)
stringReplace()
Definition: utils2.c:337
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:543
l_ok pixCopyColormap(PIX *pixd, PIX *pixs)
pixCopyColormap()
Definition: pix1.c:745
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1065
l_ok pixSwapAndDestroy(PIX **ppixd, PIX **ppixs)
pixSwapAndDestroy()
Definition: pix1.c:945
char * pixGetText(PIX *pix)
pixGetText()
Definition: pix1.c:1459
l_ok pixPrintStreamInfo(FILE *fp, PIX *pix, const char *text)
pixPrintStreamInfo()
Definition: pix1.c:1850
char * stringJoin(const char *src1, const char *src2)
stringJoin()
Definition: utils2.c:509
Definition: pix.h:134
void *(* alloc_fn)(size_t)
Definition: pix.h:1336
PIX * pixCopy(PIX *pixd, PIX *pixs)
pixCopy()
Definition: pix1.c:628
l_uint32 wpl
Definition: pix.h:140
l_ok pixSetResolution(PIX *pix, l_int32 xres, l_int32 yres)
pixSetResolution()
Definition: pix1.c:1339
PIXCMAP * pixcmapCopy(PIXCMAP *cmaps)
pixcmapCopy()
Definition: colormap.c:234
l_ok pixCopyDimensions(PIX *pixd, const PIX *pixs)
pixCopyDimensions()
Definition: pix1.c:1116
l_ok pixCopySpp(PIX *pixd, const PIX *pixs)
pixCopySpp()
Definition: pix1.c:1188
l_ok pixTransferAllData(PIX *pixd, PIX **ppixs, l_int32 copytext, l_int32 copyformat)
pixTransferAllData()
Definition: pix1.c:855
l_int32 pixSizesEqual(const PIX *pix1, const PIX *pix2)
pixSizesEqual()
Definition: pix1.c:781
void setPixMemoryManager(alloc_fn allocator, dealloc_fn deallocator)
setPixMemoryManager()
Definition: pix1.c:282
l_ok pixAddText(PIX *pix, const char *textstring)
pixAddText()
Definition: pix1.c:1511
l_uint32 spp
Definition: pix.h:139