jint Java_com_googlecode_leptonica_android_ReadFile_nativeReadBytes8(JNIEnv *env, jclass clazz, jbyteArray data, jint w, jint h) { LOGV(__FUNCTION__); PIX *pix = pixCreateNoInit((l_int32) w, (l_int32) h, 8); l_uint8 **lineptrs = pixSetupByteProcessing(pix, NULL, NULL); jbyte *data_buffer = env->GetByteArrayElements(data, NULL); l_uint8 *byte_buffer = (l_uint8 *) data_buffer; for (int i = 0; i < h; i++) { memcpy(lineptrs[i], (byte_buffer + (i * w)), w); } env->ReleaseByteArrayElements(data, data_buffer, JNI_ABORT); pixCleanupByteProcessing(pix, lineptrs); l_int32 d; pixGetDimensions(pix, &w, &h, &d); LOGE("Created image width w=%d, h=%d, d=%d", w, h, d); return (jint) pix; }
/*! * pixCreate() * * Input: width, height, depth * Return: pixd (with data allocated and initialized to 0), * or null on error */ PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth) { PIX *pixd; PROCNAME("pixCreate"); if ((pixd = pixCreateNoInit(width, height, depth)) == NULL) return (PIX *)ERROR_PTR("pixd not made", procName, NULL); memset(pixd->data, 0, 4 * pixd->wpl * pixd->h); return pixd; }
/*! * pixCreateTemplateNoInit() * * Input: pixs * Return: pixd, or null on error * * Notes: * (1) Makes a Pix of the same size as the input Pix, with * the data array allocated but not initialized to 0. * (2) Copies the other fields, including colormap if it exists. */ PIX * pixCreateTemplateNoInit(PIX *pixs) { l_int32 w, h, d; PIX *pixd; PROCNAME("pixCreateTemplateNoInit"); if (!pixs) return (PIX *)ERROR_PTR("pixs not defined", procName, NULL); pixGetDimensions(pixs, &w, &h, &d); if ((pixd = pixCreateNoInit(w, h, d)) == NULL) return (PIX *)ERROR_PTR("pixd not made", procName, NULL); pixCopyResolution(pixd, pixs); pixCopyColormap(pixd, pixs); pixCopyText(pixd, pixs); pixCopyInputFormat(pixd, pixs); return pixd; }
/*! * pixSauvolaBinarizeTiled() * * Input: pixs (8 bpp grayscale, not colormapped) * whsize (window half-width for measuring local statistics) * factor (factor for reducing threshold due to variance; >= 0) * nx, ny (subdivision into tiles; >= 1) * &pixth (<optional return> Sauvola threshold values) * &pixd (<optional return> thresholded image) * Return: 0 if OK, 1 on error * * Notes: * (1) The window width and height are 2 * @whsize + 1. The minimum * value for @whsize is 2; typically it is >= 7.. * (2) For nx == ny == 1, this defaults to pixSauvolaBinarize(). * (3) Why a tiled version? * (a) Because the mean value accumulator is a uint32, overflow * can occur for an image with more than 16M pixels. * (b) The mean value accumulator array for 16M pixels is 64 MB. * The mean square accumulator array for 16M pixels is 128 MB. * Using tiles reduces the size of these arrays. * (c) Each tile can be processed independently, in parallel, * on a multicore processor. * (4) The Sauvola threshold is determined from the formula: * t = m * (1 - k * (1 - s / 128)) * See pixSauvolaBinarize() for details. */ l_int32 pixSauvolaBinarizeTiled(PIX *pixs, l_int32 whsize, l_float32 factor, l_int32 nx, l_int32 ny, PIX **ppixth, PIX **ppixd) { l_int32 i, j, w, h, xrat, yrat; PIX *pixth, *pixd, *tileth, *tiled, *pixt; PIX **ptileth, **ptiled; PIXTILING *pt; PROCNAME("pixSauvolaBinarizeTiled"); if (!ppixth && !ppixd) return ERROR_INT("no outputs", procName, 1); if (ppixth) *ppixth = NULL; if (ppixd) *ppixd = NULL; if (!pixs || pixGetDepth(pixs) != 8) return ERROR_INT("pixs undefined or not 8 bpp", procName, 1); if (pixGetColormap(pixs)) return ERROR_INT("pixs is cmapped", procName, 1); pixGetDimensions(pixs, &w, &h, NULL); if (whsize < 2) return ERROR_INT("whsize must be >= 2", procName, 1); if (w < 2 * whsize + 3 || h < 2 * whsize + 3) return ERROR_INT("whsize too large for image", procName, 1); if (factor < 0.0) return ERROR_INT("factor must be >= 0", procName, 1); if (nx <= 1 && ny <= 1) return pixSauvolaBinarize(pixs, whsize, factor, 1, NULL, NULL, ppixth, ppixd); /* Test to see if the tiles are too small. The required * condition is that the tile dimensions must be at least * (whsize + 2) x (whsize + 2). */ xrat = w / nx; yrat = h / ny; if (xrat < whsize + 2) { nx = w / (whsize + 2); L_WARNING("tile width too small; nx reduced to %d\n", procName, nx); } if (yrat < whsize + 2) { ny = h / (whsize + 2); L_WARNING("tile height too small; ny reduced to %d\n", procName, ny); } if (nx <= 1 && ny <= 1) return pixSauvolaBinarize(pixs, whsize, factor, 1, NULL, NULL, ppixth, ppixd); /* We can use pixtiling for painting both outputs, if requested */ if (ppixth) { pixth = pixCreateNoInit(w, h, 8); *ppixth = pixth; } if (ppixd) { pixd = pixCreateNoInit(w, h, 1); *ppixd = pixd; } pt = pixTilingCreate(pixs, nx, ny, 0, 0, whsize + 1, whsize + 1); pixTilingNoStripOnPaint(pt); /* pixSauvolaBinarize() does the stripping */ for (i = 0; i < ny; i++) { for (j = 0; j < nx; j++) { pixt = pixTilingGetTile(pt, i, j); ptileth = (ppixth) ? &tileth : NULL; ptiled = (ppixd) ? &tiled : NULL; pixSauvolaBinarize(pixt, whsize, factor, 0, NULL, NULL, ptileth, ptiled); if (ppixth) { /* do not strip */ pixTilingPaintTile(pixth, i, j, tileth, pt); pixDestroy(&tileth); } if (ppixd) { pixTilingPaintTile(pixd, i, j, tiled, pt); pixDestroy(&tiled); } pixDestroy(&pixt); } } pixTilingDestroy(&pt); return 0; }