/* Returns 1 on error */ static l_int32 test_mem_gif(const char *fname, l_int32 index) { l_uint8 *data = NULL; l_int32 same; size_t size = 0; PIX *pixs; PIX *pixd = NULL; if ((pixs = pixRead(fname)) == NULL) { fprintf(stderr, "Failure to read gif file: %s\n", fname); return 1; } if (pixWriteMem(&data, &size, pixs, IFF_GIF)) { fprintf(stderr, "Mem gif write fail on image %d\n", index); return 1; } if ((pixd = pixReadMem(data, size)) == NULL) { fprintf(stderr, "Mem gif read fail on image %d\n", index); lept_free(data); return 1; } pixEqual(pixs, pixd, &same); pixDestroy(&pixs); pixDestroy(&pixd); lept_free(data); if (!same && index < 6) { fprintf(stderr, "Mem gif write/read fail for file %s\n", fname); return 1; } else return 0; }
/* Returns 1 on error */ static l_int32 test_mem_png(const char *fname) { l_uint8 *data = NULL; l_int32 same; size_t size = 0; PIX *pixs; PIX *pixd = NULL; if ((pixs = pixRead(fname)) == NULL) { fprintf(stderr, "Failure to read %s\n", fname); return 1; } if (pixWriteMem(&data, &size, pixs, IFF_PNG)) { fprintf(stderr, "Mem write fail for png\n"); return 1; } if ((pixd = pixReadMem(data, size)) == NULL) { fprintf(stderr, "Mem read fail for png\n"); lept_free(data); return 1; } pixEqual(pixs, pixd, &same); if (!same) fprintf(stderr, "Mem write/read fail for file %s\n", fname); pixDestroy(&pixs); pixDestroy(&pixd); lept_free(data); return (!same); }
// Returns the Pix image for the image_data. Must be pixDestroyed after use. Pix* ImageData::GetPixInternal(const GenericVector<char>& image_data) { Pix* pix = NULL; if (!image_data.empty()) { // Convert the array to an image. const unsigned char* u_data = reinterpret_cast<const unsigned char*>(&image_data[0]); pix = pixReadMem(u_data, image_data.size()); } return pix; }
/* Returns 1 on error */ static l_int32 test_writemem(PIX *pixs, l_int32 format, char *psfile) { l_uint8 *data = NULL; l_int32 same; size_t size = 0; PIX *pixd = NULL; if (format == IFF_PS) { pixWriteMemPS(&data, &size, pixs, NULL, 0, 1.0); l_binaryWrite(psfile, "w", data, size); lept_free(data); return 0; } /* Fail silently if library is not available */ #if !HAVE_LIBJPEG if (format == IFF_JFIF_JPEG) return 0; #endif /* !HAVE_LIBJPEG */ #if !HAVE_LIBPNG if (format == IFF_PNG) return 0; #endif /* !HAVE_LIBPNG */ #if !HAVE_LIBTIFF if (format == IFF_TIFF) return 0; #endif /* !HAVE_LIBTIFF */ if (pixWriteMem(&data, &size, pixs, format)) { fprintf(stderr, "Mem write fail for format %d\n", format); return 1; } if ((pixd = pixReadMem(data, size)) == NULL) { fprintf(stderr, "Mem read fail for format %d\n", format); lept_free(data); return 1; } if (format == IFF_JFIF_JPEG) { fprintf(stderr, "jpeg size = %ld\n", size); pixDisplayWrite(pixd, 1); same = TRUE; } else { pixEqual(pixs, pixd, &same); if (!same) fprintf(stderr, "Mem write/read fail for format %d\n", format); } pixDestroy(&pixd); lept_free(data); return (!same); }
jlong Java_com_googlecode_leptonica_android_ReadFile_nativeReadMem(JNIEnv *env, jclass clazz, jbyteArray image, jint length) { jbyte *image_buffer = env->GetByteArrayElements(image, NULL); int buffer_length = env->GetArrayLength(image); PIX *pix = pixReadMem((const l_uint8 *) image_buffer, buffer_length); env->ReleaseByteArrayElements(image, image_buffer, JNI_ABORT); return (jlong) pix; }
/*! * pixaGenerateFontFromString() * * Input: fontsize (4, 6, 8, ... , 20, in pts at 300 ppi) * &bl1 (<return> baseline of row 1) * &bl2 (<return> baseline of row 2) * &bl3 (<return> baseline of row 3) * Return: pixa of font bitmaps for 95 characters, or null on error * * Notes: * (1) See pixaGenerateFontFromFile() for details. */ PIXA * pixaGenerateFontFromString(l_int32 fontsize, l_int32 *pbl0, l_int32 *pbl1, l_int32 *pbl2) { l_uint8 *data; l_int32 redsize, nbytes; PIX *pix; PIXA *pixa; PROCNAME("pixaGenerateFontFromString"); if (!pbl0 || !pbl1 || !pbl2) return (PIXA *)ERROR_PTR("&bl not all defined", procName, NULL); *pbl0 = *pbl1 = *pbl2 = 0; redsize = (fontsize / 2) - 2; if (redsize < 0 || redsize > NUM_FONTS) return (PIXA *)ERROR_PTR("invalid font size", procName, NULL); if (fontsize == 4) { data = decodeBase64(fontdata_4, strlen(fontdata_4), &nbytes); } else if (fontsize == 6) { data = decodeBase64(fontdata_6, strlen(fontdata_6), &nbytes); } else if (fontsize == 8) { data = decodeBase64(fontdata_8, strlen(fontdata_8), &nbytes); } else if (fontsize == 10) { data = decodeBase64(fontdata_10, strlen(fontdata_10), &nbytes); } else if (fontsize == 12) { data = decodeBase64(fontdata_12, strlen(fontdata_12), &nbytes); } else if (fontsize == 14) { data = decodeBase64(fontdata_14, strlen(fontdata_14), &nbytes); } else if (fontsize == 16) { data = decodeBase64(fontdata_16, strlen(fontdata_16), &nbytes); } else if (fontsize == 18) { data = decodeBase64(fontdata_18, strlen(fontdata_18), &nbytes); } else { /* fontsize == 20 */ data = decodeBase64(fontdata_20, strlen(fontdata_20), &nbytes); } if (!data) return (PIXA *)ERROR_PTR("data not made", procName, NULL); pix = pixReadMem(data, nbytes); FREE(data); if (!pix) return (PIXA *)ERROR_PTR("pix not made", procName, NULL); pixa = pixaGenerateFont(pix, fontsize, pbl0, pbl1, pbl2); pixDestroy(&pix); return pixa; }
int main(int argc, char **argv) { char buf[512]; char *pathname, *datastr, *formstr; l_uint8 *data1, *data2; l_int32 i, bl1, bl2, bl3, sbytes, formbytes, fontsize, rbytes; size_t nbytes; PIX *pix1, *pix2, *pixd; PIXA *pixa; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; /* ------------ Generate pixa char bitmap files from file ----------- */ lept_rmdir("filefonts"); lept_mkdir("filefonts"); for (i = 0; i < 9; i++) { pixaSaveFont("fonts", "/tmp/filefonts", sizes[i]); pathname = genPathname("/tmp/filefonts", outputfonts[i]); pixa = pixaRead(pathname); if (rp->display) { fprintf(stderr, "Found %d chars in font size %d\n", pixaGetCount(pixa), sizes[i]); } pixd = pixaDisplayTiled(pixa, 1500, 0, 15); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 0 - 8 */ if (i == 2) pixDisplayWithTitle(pixd, 100, 0, NULL, rp->display); pixDestroy(&pixd); pixaDestroy(&pixa); lept_free(pathname); } lept_rmdir("filefonts"); /* ---------- Generate pixa char bitmap files from string --------- */ lept_rmdir("strfonts"); lept_mkdir("strfonts"); for (i = 0; i < 9; i++) { pixaSaveFont(NULL, "/tmp/strfonts", sizes[i]); pathname = genPathname("/tmp/strfonts", outputfonts[i]); pixa = pixaRead(pathname); if (rp->display) { fprintf(stderr, "Found %d chars in font size %d\n", pixaGetCount(pixa), sizes[i]); } pixd = pixaDisplayTiled(pixa, 1500, 0, 15); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 9 - 17 */ if (i == 2) pixDisplayWithTitle(pixd, 100, 150, NULL, rp->display); pixDestroy(&pixd); pixaDestroy(&pixa); lept_free(pathname); } /* ----- Use pixaGetFont() and write the result out -----*/ lept_rmdir("pafonts"); lept_mkdir("pafonts"); for (i = 0; i < 9; i++) { pixa = pixaGetFont("/tmp/strfonts", sizes[i], &bl1, &bl2, &bl3); fprintf(stderr, "Baselines are at: %d, %d, %d\n", bl1, bl2, bl3); snprintf(buf, sizeof(buf), "/tmp/pafonts/chars-%d.pa", sizes[i]); pixaWrite(buf, pixa); if (i == 2) { pixd = pixaDisplayTiled(pixa, 1500, 0, 15); pixDisplayWithTitle(pixd, 100, 300, NULL, rp->display); pixDestroy(&pixd); } pixaDestroy(&pixa); } lept_rmdir("pafonts"); /* ------- Generate 4/3 encoded ascii strings from tiff files ------ */ lept_rmdir("fontencode"); lept_mkdir("fontencode"); for (i = 0; i < 9; i++) { fontsize = 2 * i + 4; pathname = genPathname("fonts", inputfonts[i]); data1 = l_binaryRead(pathname, &nbytes); datastr = encodeBase64(data1, nbytes, &sbytes); if (rp->display) fprintf(stderr, "nbytes = %lu, sbytes = %d\n", (unsigned long)nbytes, sbytes); formstr = reformatPacked64(datastr, sbytes, 4, 72, 1, &formbytes); snprintf(buf, sizeof(buf), "/tmp/fontencode/formstr_%d.txt", fontsize); l_binaryWrite(buf, "w", formstr, formbytes); regTestCheckFile(rp, buf); /* 18-26 */ if (i == 8) pix1 = pixReadMem(data1, nbytes); /* original */ FREE(data1); data2 = decodeBase64(datastr, sbytes, &rbytes); snprintf(buf, sizeof(buf), "/tmp/fontencode/image_%d.tif", fontsize); l_binaryWrite(buf, "w", data2, rbytes); if (i == 8) { pix2 = pixReadMem(data2, rbytes); /* encode/decode */ regTestComparePix(rp, pix1, pix2); /* 27 */ pixDestroy(&pix1); pixDestroy(&pix2); } FREE(data2); FREE(pathname); FREE(datastr); FREE(formstr); } /* ------------ Get timing for font generation ----------- */ startTimer(); for (i = 0; i < 100; i++) { pixa = pixaGenerateFontFromString(sizes[5], &bl1, &bl2, &bl3); pixaDestroy(&pixa); } fprintf(stderr, "Time for font gen = %7.4f sec\n", stopTimer() / 100.0); return regTestCleanup(rp); }
char *internalDoScanningOperation(char *uuid, char *lang) { int request_resolution = 0; int docid; int current_page = 0; int total_requested_pages; double totbytes = 0; SANE_Status status; SANE_Handle *openDeviceHandle; SANE_Byte *raw_image; SANE_Parameters pars; char *docid_s; char *total_requested_pages_s; char *devName; char *outFilename; char *raw_image_format; char *header; o_log(DEBUGM, "doScanningOperation: sane initialized uuid(%s)",(char *)uuid); updateScanProgress(uuid, SCAN_WAITING_ON_SCANNER, 0); // Open the device devName = getScanParam(uuid, SCAN_PARAM_DEVNAME); o_log(DEBUGM, "sane_open of \"%s\"",devName); status = sane_open ((SANE_String_Const) devName, (SANE_Handle)&openDeviceHandle); if(status != SANE_STATUS_GOOD) { handleSaneErrors("Cannot open device ", devName, status, 0); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status); free(devName); return 0; } free(devName); /* ========================================================== */ if ( ! setOptions( (char *)uuid, openDeviceHandle, &request_resolution ) ) return 0; o_log(DEBUGM, "sane_start: setOptions returned request_resolution %d\n",request_resolution); int timeout = 5; while( 0 < timeout ) { status = sane_start (openDeviceHandle); if(status == SANE_STATUS_GOOD) { break; } else { if(status == SANE_STATUS_DEVICE_BUSY ) { // BUSY signal could be the scanner just having a // bit of lag - specially network connected devices timeout--; if ( timeout == 0 ) { handleSaneErrors("Cannot start scanning", "even after trying several time", status, 0); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status); return 0; } else { o_log(WARNING, "Device reports not ready to 'start', waiting 500ms. Will try another %d times", timeout); usleep(500 * 1000); // 500ms or 0.5sec } } else { handleSaneErrors("Cannot start scanning", "", status, 0); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status); return 0; } } } // Get scanning params (from the scanner) if( request_resolution == 0 ) { o_log(DEBUGM, "Resolution did not get set in scanner setup."); updateScanProgress(uuid, SCAN_INTERNAL_ERROR, 10004); return 0; } o_log(DEBUGM, "Get scanning params"); status = sane_get_parameters (openDeviceHandle, &pars); o_log(INFORMATION, "Scanner Parm : stat=%s form=%d,lf=%d,bpl=%d,pixpl=%d,lin=%d,dep=%d", sane_strstatus (status), pars.format, pars.last_frame, pars.bytes_per_line, pars.pixels_per_line, pars.lines, pars.depth); switch (pars.format) { case SANE_FRAME_GRAY: o_log(DEBUGM, "Expecting Gray data (1 channel only)."); raw_image_format = o_strdup( "P5" ); break; case SANE_FRAME_RGB: o_log(DEBUGM, "Expecting RGB data (3 channels)."); raw_image_format = o_strdup( "P6" ); break; default: o_log(DEBUGM, "backend returns three frames speratly. We do not currently support this."); updateScanProgress(uuid, SCAN_INTERNAL_ERROR, 10003); return 0; break; } header = o_printf ("%s\n# SANE data follows\n%d %d\n%d\n", raw_image_format, pars.pixels_per_line, pars.lines, (pars.depth <= 8) ? 255 : 65535); free( raw_image_format ); // Save Record // docid_s = getScanParam(uuid, SCAN_PARAM_DOCID); total_requested_pages_s = getScanParam(uuid, SCAN_PARAM_REQUESTED_PAGES); total_requested_pages = atoi(total_requested_pages_s); free(total_requested_pages_s); if( docid_s == NULL ) { o_log(DEBUGM, "Saving record"); updateScanProgress(uuid, SCAN_DB_WORKING, 0); docid_s = addNewScannedDoc(pars.lines, pars.pixels_per_line, request_resolution, total_requested_pages); setScanParam(uuid, SCAN_PARAM_DOCID, docid_s); setScanParam(uuid, SCAN_PARAM_ON_PAGE, "1"); current_page = 1; } else { char *current_page_s = getScanParam(uuid, SCAN_PARAM_ON_PAGE); current_page = atoi(current_page_s); free(current_page_s); current_page++; current_page_s = itoa(current_page, 10); setScanParam(uuid, SCAN_PARAM_ON_PAGE, current_page_s); free(current_page_s); } docid = atoi(docid_s); free(docid_s); totbytes = (double)((pars.bytes_per_line * pars.lines)); /* ========================================================== */ raw_image = collectData( (char *)uuid, openDeviceHandle, totbytes, pars.bytes_per_line, header ); o_log(INFORMATION, "Scanning done."); o_log(DEBUGM, "sane_cancel"); sane_cancel(openDeviceHandle); o_log(DEBUGM, "sane_close"); sane_close(openDeviceHandle); // Convert Raw into JPEG // updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 0); PIX *pix; if ( ( pix = pixReadMem( raw_image, (pars.bytes_per_line*pars.lines)+strlen(header) ) ) == NULL) { o_log(ERROR, "Could not load the image data into a PIX"); } updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 55); o_log(INFORMATION, "Convertion process: Loaded (depth: %d)", pixGetDepth(pix)); free(raw_image); free(header); outFilename = o_printf("%s/scans/%d_%d.jpg", BASE_DIR, docid, current_page); pixWrite(outFilename, pix, IFF_JFIF_JPEG); free(outFilename); updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 100); o_log(INFORMATION, "Conversion process: Complete"); // Do OCR - on this page // - OCR libs just wants the raw data and not the image header ocrImage( uuid, docid, current_page, request_resolution, pix, lang ); #ifdef CAN_PHASH // Calulate the pHash, so we can compare images later if( current_page == 1 ) { updateScanProgress(uuid, SCAN_CALULATING_PHASH, 0); unsigned long long hash = getImagePhash_px( pix ); savePhash( docid, hash ); } #endif /* CAN_PHASH */ pixDestroy( &pix ); // cleaup && What should we do next // o_log(DEBUGM, "mostly done."); if(current_page >= total_requested_pages) updateScanProgress(uuid, SCAN_FINISHED, docid); else updateScanProgress(uuid, SCAN_WAITING_ON_NEW_PAGE, ++current_page); o_log(DEBUGM, "Page scan done."); return o_strdup("OK"); }
int main(int argc, char **argv) { if ((argc == 2 && strcmp(argv[1], "-v") == 0) || (argc == 2 && strcmp(argv[1], "--version") == 0)) { char *versionStrP; fprintf(stderr, "tesseract %s\n", tesseract::TessBaseAPI::Version()); versionStrP = getLeptonicaVersion(); fprintf(stderr, " %s\n", versionStrP); lept_free(versionStrP); versionStrP = getImagelibVersions(); fprintf(stderr, " %s\n", versionStrP); lept_free(versionStrP); #ifdef USE_OPENCL cl_platform_id platform; cl_uint num_platforms; cl_device_id devices[2]; cl_uint num_devices; char info[256]; int i; fprintf(stderr, " OpenCL info:\n"); clGetPlatformIDs(1, &platform, &num_platforms); fprintf(stderr, " Found %d platforms.\n", num_platforms); clGetPlatformInfo(platform, CL_PLATFORM_NAME, 256, info, 0); fprintf(stderr, " Platform name: %s.\n", info); clGetPlatformInfo(platform, CL_PLATFORM_VERSION, 256, info, 0); fprintf(stderr, " Version: %s.\n", info); clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 2, devices, &num_devices); fprintf(stderr, " Found %d devices.\n", num_devices); for (i = 0; i < num_devices; ++i) { clGetDeviceInfo(devices[i], CL_DEVICE_NAME, 256, info, 0); fprintf(stderr, " Device %d name: %s.\n", i+1, info); } #endif exit(0); } // Make the order of args a bit more forgiving than it used to be. const char* lang = "eng"; const char* image = NULL; const char* output = NULL; const char* datapath = NULL; bool noocr = false; bool list_langs = false; bool print_parameters = false; tesseract::PageSegMode pagesegmode = tesseract::PSM_AUTO; int arg = 1; while (arg < argc && (output == NULL || argv[arg][0] == '-')) { if (strcmp(argv[arg], "-l") == 0 && arg + 1 < argc) { lang = argv[arg + 1]; ++arg; } else if (strcmp(argv[arg], "--tessdata-dir") == 0 && arg + 1 < argc) { datapath = argv[arg + 1]; ++arg; } else if (strcmp(argv[arg], "--list-langs") == 0) { noocr = true; list_langs = true; } else if (strcmp(argv[arg], "-psm") == 0 && arg + 1 < argc) { pagesegmode = static_cast<tesseract::PageSegMode>(atoi(argv[arg + 1])); ++arg; } else if (strcmp(argv[arg], "--print-parameters") == 0) { noocr = true; print_parameters = true; } else if (strcmp(argv[arg], "-c") == 0 && arg + 1 < argc) { // handled properly after api init ++arg; } else if (image == NULL) { image = argv[arg]; } else if (output == NULL) { output = argv[arg]; } ++arg; } if (argc == 2 && strcmp(argv[1], "--list-langs") == 0) { list_langs = true; noocr = true; } if (output == NULL && noocr == false) { fprintf(stderr, "Usage:\n %s imagename|stdin outputbase|stdout " "[options...] [configfile...]\n\n", argv[0]); fprintf(stderr, "OCR options:\n"); fprintf(stderr, " --tessdata-dir /path\tspecify location of tessdata" " path\n"); fprintf(stderr, " -l lang[+lang]\tspecify language(s) used for OCR\n"); fprintf(stderr, " -c configvar=value\tset value for control parameter.\n" "\t\t\tMultiple -c arguments are allowed.\n"); fprintf(stderr, " -psm pagesegmode\tspecify page segmentation mode.\n"); fprintf(stderr, "These options must occur before any configfile.\n\n"); fprintf(stderr, "pagesegmode values are:\n" " 0 = Orientation and script detection (OSD) only.\n" " 1 = Automatic page segmentation with OSD.\n" " 2 = Automatic page segmentation, but no OSD, or OCR\n" " 3 = Fully automatic page segmentation, but no OSD. (Default)\n" " 4 = Assume a single column of text of variable sizes.\n" " 5 = Assume a single uniform block of vertically aligned text.\n" " 6 = Assume a single uniform block of text.\n" " 7 = Treat the image as a single text line.\n" " 8 = Treat the image as a single word.\n" " 9 = Treat the image as a single word in a circle.\n" " 10 = Treat the image as a single character.\n\n"); fprintf(stderr, "Single options:\n"); fprintf(stderr, " -v --version: version info\n"); fprintf(stderr, " --list-langs: list available languages for tesseract " "engine. Can be used with --tessdata-dir.\n"); fprintf(stderr, " --print-parameters: print tesseract parameters to the " "stdout.\n"); exit(1); } if (output != NULL && strcmp(output, "-") && strcmp(output, "stdout")) { tprintf("Tesseract Open Source OCR Engine v%s with Leptonica\n", tesseract::TessBaseAPI::Version()); } PERF_COUNT_START("Tesseract:main") tesseract::TessBaseAPI api; api.SetOutputName(output); int rc = api.Init(datapath, lang, tesseract::OEM_DEFAULT, &(argv[arg]), argc - arg, NULL, NULL, false); if (rc) { fprintf(stderr, "Could not initialize tesseract.\n"); exit(1); } char opt1[255], opt2[255]; for (arg = 0; arg < argc; arg++) { if (strcmp(argv[arg], "-c") == 0 && arg + 1 < argc) { strncpy(opt1, argv[arg + 1], 255); *(strchr(opt1, '=')) = 0; strncpy(opt2, strchr(argv[arg + 1], '=') + 1, 255); opt2[254] = 0; ++arg; if (!api.SetVariable(opt1, opt2)) { fprintf(stderr, "Could not set option: %s=%s\n", opt1, opt2); } } } if (list_langs) { GenericVector<STRING> languages; api.GetAvailableLanguagesAsVector(&languages); fprintf(stderr, "List of available languages (%d):\n", languages.size()); for (int index = 0; index < languages.size(); ++index) { STRING& string = languages[index]; fprintf(stderr, "%s\n", string.string()); } api.End(); exit(0); } if (print_parameters) { FILE* fout = stdout; fprintf(stdout, "Tesseract parameters:\n"); api.PrintVariables(fout); api.End(); exit(0); } // We have 2 possible sources of pagesegmode: a config file and // the command line. For backwards compatability reasons, the // default in tesseract is tesseract::PSM_SINGLE_BLOCK, but the // default for this program is tesseract::PSM_AUTO. We will let // the config file take priority, so the command-line default // can take priority over the tesseract default, so we use the // value from the command line only if the retrieved mode // is still tesseract::PSM_SINGLE_BLOCK, indicating no change // in any config file. Therefore the only way to force // tesseract::PSM_SINGLE_BLOCK is from the command line. // It would be simpler if we could set the value before Init, // but that doesn't work. if (api.GetPageSegMode() == tesseract::PSM_SINGLE_BLOCK) api.SetPageSegMode(pagesegmode); bool stdInput = !strcmp(image, "stdin") || !strcmp(image, "-"); Pix* pixs = NULL; if (stdInput) { char byt; GenericVector<l_uint8> ch_data; std::istream file(std::cin.rdbuf()); #ifdef WIN32 if (_setmode(_fileno(stdin), _O_BINARY) == -1) tprintf("ERROR: cin to binary: %s", strerror(errno)); #endif // WIN32 while (file.get(byt)) { ch_data.push_back(byt); } std::cin.ignore(std::cin.rdbuf()->in_avail() + 1); pixs = pixReadMem(&ch_data[0], ch_data.size()); } if (pagesegmode == tesseract::PSM_AUTO_ONLY || pagesegmode == tesseract::PSM_OSD_ONLY) { int ret_val = 0; if (!pixs) pixs = pixRead(image); if (!pixs) { fprintf(stderr, "Cannot open input file: %s\n", image); exit(2); } api.SetImage(pixs); if (pagesegmode == tesseract::PSM_OSD_ONLY) { OSResults osr; if (api.DetectOS(&osr)) { int orient = osr.best_result.orientation_id; int script_id = osr.get_best_script(orient); float orient_oco = osr.best_result.oconfidence; float orient_sco = osr.best_result.sconfidence; tprintf("Orientation: %d\nOrientation in degrees: %d\n" \ "Orientation confidence: %.2f\n" \ "Script: %d\nScript confidence: %.2f\n", orient, OrientationIdToValue(orient), orient_oco, script_id, orient_sco); } else { ret_val = 1; } } else { tesseract::Orientation orientation; tesseract::WritingDirection direction; tesseract::TextlineOrder order; float deskew_angle; tesseract::PageIterator* it = api.AnalyseLayout(); if (it) { it->Orientation(&orientation, &direction, &order, &deskew_angle); tprintf("Orientation: %d\nWritingDirection: %d\nTextlineOrder: %d\n" \ "Deskew angle: %.4f\n", orientation, direction, order, deskew_angle); } else { ret_val = 1; } delete it; } pixDestroy(&pixs); exit(ret_val); } tesseract::TessResultRenderer* renderer = NULL; bool b; api.GetBoolVariable("tessedit_create_hocr", &b); if (b && renderer == NULL) renderer = new tesseract::TessHOcrRenderer(); api.GetBoolVariable("tessedit_create_pdf", &b); if (b && renderer == NULL) renderer = new tesseract::TessPDFRenderer(api.GetDatapath()); api.GetBoolVariable("tessedit_create_boxfile", &b); if (b && renderer == NULL) renderer = new tesseract::TessBoxTextRenderer(); if (renderer == NULL) renderer = new tesseract::TessTextRenderer(); if (pixs) { api.ProcessPage(pixs, 0, NULL, NULL, 0, renderer); pixDestroy(&pixs); } else { FILE* fin = fopen(image, "rb"); if (fin == NULL) { fprintf(stderr, "Cannot open input file: %s\n", image); exit(2); } fclose(fin); if (!api.ProcessPages(image, NULL, 0, renderer)) { fprintf(stderr, "Error during processing.\n"); exit(1); } } FILE* fout = stdout; if (strcmp(output, "-") && strcmp(output, "stdout")) { STRING outfile = STRING(output) + STRING(".") + STRING(renderer->file_extension()); fout = fopen(outfile.string(), "wb"); if (fout == NULL) { fprintf(stderr, "Cannot create output file %s\n", outfile.string()); exit(1); } } const char* data; inT32 data_len; if (renderer->GetOutput(&data, &data_len)) { fwrite(data, 1, data_len, fout); if (fout != stdout) fclose(fout); else clearerr(fout); } PERF_COUNT_END return 0; // Normal exit }