Beispiel #1
0
int main(int    argc,
         char **argv)
{
SEL         *sel1, *sel2, *sel3, *sel4;
SELA        *sela;
PIX         *pix, *pixd;
PIXA        *pixa;
static char  mainName[] = "flipselgen";

    if (argc != 1)
        return ERROR_INT(" Syntax: flipselgen", mainName, 1);

    sela = selaCreate(0);
    sel1 = selCreateFromString(textsel1, 5, 6, "flipsel1");
    sel2 = selCreateFromString(textsel2, 5, 6, "flipsel2");
    sel3 = selCreateFromString(textsel3, 5, 6, "flipsel3");
    sel4 = selCreateFromString(textsel4, 5, 6, "flipsel4");
    selaAddSel(sela, sel1, NULL, 0);
    selaAddSel(sela, sel2, NULL, 0);
    selaAddSel(sela, sel3, NULL, 0);
    selaAddSel(sela, sel4, NULL, 0);

    pixa = pixaCreate(4);
    pix = selDisplayInPix(sel1, 23, 2);
    pixDisplayWithTitle(pix, 100, 100, "sel1", DFLAG);
    pixaAddPix(pixa, pix, L_INSERT);
    pix = selDisplayInPix(sel2, 23, 2);
    pixDisplayWithTitle(pix, 275, 100, "sel2", DFLAG);
    pixaAddPix(pixa, pix, L_INSERT);
    pix = selDisplayInPix(sel3, 23, 2);
    pixDisplayWithTitle(pix, 450, 100, "sel3", DFLAG);
    pixaAddPix(pixa, pix, L_INSERT);
    pix = selDisplayInPix(sel4, 23, 2);
    pixDisplayWithTitle(pix, 625, 100, "sel4", DFLAG);
    pixaAddPix(pixa, pix, L_INSERT);

    pixd = pixaDisplayTiled(pixa, 800, 0, 15);
    pixDisplayWithTitle(pixd, 100, 300, "allsels", DFLAG);
    pixDestroy(&pixd);
    pixaDestroy(&pixa);

    if (fhmtautogen(sela, INDEX, NULL))
        return ERROR_INT(" Generation failed", mainName, 1);

    selaDestroy(&sela);
    return 0;
}
Beispiel #2
0
std::vector<Figure> extractFigures(PIX *original, PageRegions &pageRegions,
                                   DocumentStatistics &docStats, bool verbose,
                                   bool showSteps,
                                   std::vector<Figure> &errors) {
  BOXA *bodytext = pageRegions.bodytext;
  BOXA *graphics = pageRegions.graphics;
  BOXA *captions = pageRegions.getCaptionsBoxa();
  std::vector<Caption> unassigned_captions = pageRegions.captions;
  int total_captions = captions->n;

  PIXA *steps = showSteps ? pixaCreate(4) : NULL;

  // Add bodyText boxes to fill up the margin
  BOX *margin;
  BOX *foreground;
  pixClipToForeground(original, NULL, &foreground);
  BOX *extent;
  boxaGetExtent(graphics, NULL, NULL, &extent);
  margin = boxBoundingRegion(extent, foreground);
  boxDestroy(&extent);
  boxaGetExtent(bodytext, NULL, NULL, &extent);
  margin = boxBoundingRegion(margin, extent);
  boxDestroy(&extent);
  boxaGetExtent(pageRegions.other, NULL, NULL, &extent);
  margin = boxBoundingRegion(margin, extent);
  int x = margin->x - 2, y = margin->y - 2, h = margin->h + 4,
      w = margin->w + 4;
  x = std::max(x, 0);
  y = std::max(y, 0);
  h = std::min((int)original->h, h);
  w = std::min((int)original->w, w);
  boxDestroy(&margin);
  boxaAddBox(bodytext, boxCreate(0, 0, original->w, y), L_CLONE);
  boxaAddBox(bodytext, boxCreate(0, y + h, original->w, original->h - y - h),
             L_CLONE);
  boxaAddBox(bodytext, boxCreate(0, 0, x, original->h), L_CLONE);
  boxaAddBox(bodytext, boxCreate(x + w, 0, original->w - x - w, original->h),
             L_CLONE);

  // Add captions to body text
  boxaJoin(bodytext, captions, 0, captions->n);

  if (showSteps)
    pixaAddPix(steps, original, L_CLONE);

  // Generate proposed regions for each caption box
  double center = original->w / 2.0;
  BOXAA *allProposals = boxaaCreate(captions->n);
  BOXA *claimedImages = boxaCreate(captions->n);
  for (int i = 0; i < captions->n; i++) {
    BOX *captBox = boxaGetBox(captions, i, L_CLONE);
    BOXA *proposals = boxaCreate(4);
    for (int j = 0; j < bodytext->n; j++) {
      BOX *txtBox = boxaGetBox(bodytext, j, L_CLONE);
      BOX *proposal = NULL;
      int tolerance = 2;
      int horizontal = 0;
      int vertical = 0;

      boxAlignment(captBox, txtBox, tolerance, &horizontal, &vertical);
      if (vertical * horizontal != 0 or (vertical == 0 and horizontal == 0)) {
        continue;
      }

      if (vertical == 0) {
        if (horizontal == 1) {
          proposal = boxRelocateOneSide(NULL, captBox,
                                        txtBox->x + txtBox->w + 2, L_FROM_LEFT);
        } else if (horizontal == -1) {
          proposal =
              boxRelocateOneSide(NULL, captBox, txtBox->x - 2, L_FROM_RIGHT);
        }
        boxExpandUD(proposal, bodytext);
        if (horizontal == -1) {
          proposal->w -= captBox->w + 1;
          proposal->x = captBox->x + captBox->w + 1;
        } else if (horizontal == 1) {
          proposal->w -= captBox->w + 1;
        }
      } else {
        if (vertical == 1) {
          proposal = boxRelocateOneSide(NULL, captBox,
                                        txtBox->y + txtBox->h + 3, L_FROM_TOP);
        } else if (vertical == -1) {
          proposal =
              boxRelocateOneSide(NULL, captBox, txtBox->y - 3, L_FROM_BOT);
        }
        boxExpandLR(proposal, bodytext);
        if (vertical == -1) {
          proposal->h -= captBox->h + 1;
          proposal->y = captBox->y + captBox->h + 1;
        } else if (vertical == 1) {
          proposal->h -= captBox->h + 1;
        }
      }

      // For two columns document, captions that do not
      // cross the center should not have regions pass the center
      if (docStats.documentIsTwoColumn()) {
        if (captBox->x + captBox->w <= center and
            proposal->x + proposal->w > center) {
          boxRelocateOneSide(proposal, proposal, center - 1, L_FROM_RIGHT);
        } else if (captBox->x >= center and proposal->x < center) {
          boxRelocateOneSide(proposal, proposal, center + 1, L_FROM_LEFT);
        }
      }

      BOX *clippedProposal;
      pixClipBoxToForeground(original, proposal, NULL, &clippedProposal);
      if (clippedProposal != NULL and
          scoreBox(clippedProposal, pageRegions.captions.at(i).type, bodytext,
                   graphics, claimedImages, original) > 0) {
        boxaAddBox(proposals, clippedProposal, L_CLONE);
      }
    }

    if (proposals->n > 0) {
      boxaaAddBoxa(allProposals, proposals, L_CLONE);
    } else {
      // Give up on this caption
      int on_caption = i - (total_captions - unassigned_captions.size());
      errors.push_back(Figure(unassigned_captions.at(on_caption), NULL));
      unassigned_captions.erase(unassigned_captions.begin() + on_caption);
    }
  }
  std::vector<Figure> figures = std::vector<Figure>();
  if (unassigned_captions.size() == 0) {
    return figures;
  }

  // Now go through every possible assignment of captions
  // to proposals pick the highest scorign one
  int numConfigurations = 1;
  for (int i = 0; i < allProposals->n; ++i) {
    numConfigurations *= allProposals->boxa[i]->n;
  }

  if (verbose)
    printf("Found %d possible configurations\n", numConfigurations);

  BOXA *bestProposals = NULL;
  std::vector<bool> bestKeep;
  int bestFound = -1;
  double bestScore = -1;
  for (int onConfig = 0; onConfig < numConfigurations; ++onConfig) {

    // Gather the proposed regions based on the configuration number
    int configNum = onConfig;
    BOXA *proposals = boxaCreate(allProposals->n);
    std::vector<bool> keep;
    for (int i = 0; i < allProposals->n; ++i) {
      int numProposals = allProposals->boxa[i]->n;
      int selected = configNum % numProposals;
      configNum = configNum / numProposals;
      boxaAddBox(proposals, allProposals->boxa[i]->box[selected], L_COPY);
    }

    // Attempt to split any overlapping regions
    for (int i = 0; i < proposals->n; ++i) {
      for (int j = i; j < proposals->n; ++j) {
        BOX *p1 = proposals->box[i];
        BOX *p2 = proposals->box[j];
        int eq;
        boxEqual(p1, p2, &eq);
        if (not eq)
          continue;
        int vertical, horizontal;
        boxAlignment(unassigned_captions.at(i).boundingBox,
                     unassigned_captions.at(j).boundingBox, 2, &horizontal,
                     &vertical);
        if (vertical == 0 or horizontal != 0)
          continue;

        double split = splitBoxVertical(original, p1);
        if (split > 0) {
          BOX *topClipped;
          BOX *botClipped;
          BOX *top = boxRelocateOneSide(NULL, p1, split - 1, L_FROM_BOT);
          pixClipBoxToForeground(original, top, NULL, &topClipped);
          BOX *bot = boxRelocateOneSide(NULL, p1, split + 1, L_FROM_TOP);
          pixClipBoxToForeground(original, bot, NULL, &botClipped);
          if (vertical == -1) {
            proposals->box[i] = topClipped;
            proposals->box[j] = botClipped;
          } else {
            proposals->box[i] = botClipped;
            proposals->box[j] = topClipped;
          }
          if (verbose)
            printf("Split a region vertically\n");
        }
      }
    }

    if (showSteps) {
      pixaAddPix(steps, pixDrawBoxa(original, proposals, 4, 0xff000000),
                 L_CLONE);
    }

    // Score the proposals
    int numFound = 0;
    double totalScore = 0;
    for (int i = 0; i < proposals->n; ++i) {
      double score =
          scoreBox(proposals->box[i], pageRegions.captions.at(i).type, bodytext,
                   graphics, proposals, original);
      totalScore += score;
      if (score > 0) {
        numFound += 1;
        keep.push_back(true);
      } else {
        keep.push_back(false);
      }
    }

    // Switch in for the current best needed
    if (numFound > bestFound or
        (numFound == bestFound and totalScore > bestScore)) {
      bestFound = numFound;
      bestScore = totalScore;
      bestProposals = proposals;
      bestKeep = keep;
    }
  }

  if (showSteps) {
    BOX *clip;
    PIXA *show = pixaCreate(4);
    pixClipBoxToForeground(original, NULL, NULL, &clip);
    int pad = 10;
    clip->x -= 10;
    clip->y -= 10;
    clip->w += pad * 2;
    clip->h += pad * 2;
    for (int i = 0; i < steps->n; ++i) {
      pixaAddPix(show, pixClipRectangle(steps->pix[i], clip, NULL), L_CLONE);
    }
    pixDisplay(pixaDisplayTiled(pixaConvertTo32(show), 4000, 1, 30), 0, 0);
  }

  for (int i = 0; i < bestProposals->n; ++i) {
    if (bestKeep.at(i)) {
      BOX *imageBox = bestProposals->box[i];
      int pad = 2;
      imageBox->x -= pad;
      imageBox->y -= pad;
      imageBox->w += pad * 2;
      imageBox->h += pad * 2;
      figures.push_back(Figure(unassigned_captions.at(i), imageBox));
    } else {
      errors.push_back(Figure(unassigned_captions.at(i), NULL));
    }
  }
  return figures;
}
Beispiel #3
0
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);
}
/*!
 *  pixaGenerateFont()
 *
 *      Input:  pix (of 95 characters in 3 rows)
 *              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) This does all the work.  See pixaGenerateFontFromFile()
 *          for an overview.
 *      (2) The pix is for one of the 9 fonts.  @fontsize is only
 *          used here for debugging.
 */
PIXA *
pixaGenerateFont(PIX      *pixs,
                 l_int32   fontsize,
                 l_int32  *pbl0,
                 l_int32  *pbl1,
                 l_int32  *pbl2)
{
l_int32   i, j, nrows, nrowchars, nchars, h, yval;
l_int32   width, height;
l_int32   baseline[3];
l_int32  *tab = NULL;
BOX      *box, *box1, *box2;
BOXA     *boxar, *boxac, *boxacs;
PIX      *pix1, *pix2, *pixr, *pixrc, *pixc;
PIXA     *pixa;
l_int32   n, w, inrow, top;
l_int32  *ia;
NUMA     *na;

    PROCNAME("pixaGenerateFont");

    if (!pbl0 || !pbl1 || !pbl2)
        return (PIXA *)ERROR_PTR("&bl not all defined", procName, NULL);
    *pbl0 = *pbl1 = *pbl2 = 0;
    if (!pixs)
        return (PIXA *)ERROR_PTR("pixs not defined", procName, NULL);

        /* Locate the 3 rows of characters */
    w = pixGetWidth(pixs);
    na = pixCountPixelsByRow(pixs, NULL);
    boxar = boxaCreate(0);
    n = numaGetCount(na);
    ia = numaGetIArray(na);
    inrow = 0;
    for (i = 0; i < n; i++) {
        if (!inrow && ia[i] > 0) {
            inrow = 1;
            top = i;
        } else if (inrow && ia[i] == 0) {
            inrow = 0;
            box = boxCreate(0, top, w, i - top);
            boxaAddBox(boxar, box, L_INSERT);
        }
    }
    FREE(ia);
    numaDestroy(&na);
    nrows = boxaGetCount(boxar);
#if  DEBUG_FONT_GEN
    L_INFO("For fontsize %s, have %d rows\n", procName, fontsize, nrows);
#endif  /* DEBUG_FONT_GEN */
    if (nrows != 3) {
        L_INFO("nrows = %d; skipping fontsize %d\n", procName, nrows, fontsize);
        return (PIXA *)ERROR_PTR("3 rows not generated", procName, NULL);
    }

        /* Grab the character images and baseline data */
#if DEBUG_BASELINE
    lept_rmdir("baseline");
    lept_mkdir("baseline");
#endif  /* DEBUG_BASELINE */
    tab = makePixelSumTab8();
    pixa = pixaCreate(95);
    for (i = 0; i < nrows; i++) {
        box = boxaGetBox(boxar, i, L_CLONE);
        pixr = pixClipRectangle(pixs, box, NULL);  /* row of chars */
        pixGetTextBaseline(pixr, tab, &yval);
        baseline[i] = yval;

#if DEBUG_BASELINE
        L_INFO("Baseline info: row %d, yval = %d, h = %d\n", procName,
               i, yval, pixGetHeight(pixr));
        pix1 = pixCopy(NULL, pixr);
        pixRenderLine(pix1, 0, yval, pixGetWidth(pix1), yval, 1,
                      L_FLIP_PIXELS);
        if (i == 0 )
            pixWrite("/tmp/baseline/row0.png", pix1, IFF_PNG);
        else if (i == 1)
            pixWrite("/tmp/baseline/row1.png", pix1, IFF_PNG);
        else
            pixWrite("/tmp/baseline/row2.png", pix1, IFF_PNG);
        pixDestroy(&pix1);
#endif  /* DEBUG_BASELINE */

        boxDestroy(&box);
        pixrc = pixCloseSafeBrick(NULL, pixr, 1, 35);
        boxac = pixConnComp(pixrc, NULL, 8);
        boxacs = boxaSort(boxac, L_SORT_BY_X, L_SORT_INCREASING, NULL);
        if (i == 0) {  /* consolidate the two components of '"' */
            box1 = boxaGetBox(boxacs, 1, L_CLONE);
            box2 = boxaGetBox(boxacs, 2, L_CLONE);
            box1->w = box2->x + box2->w - box1->x;  /* increase width */
            boxDestroy(&box1);
            boxDestroy(&box2);
            boxaRemoveBox(boxacs, 2);
        }
        h = pixGetHeight(pixr);
        nrowchars = boxaGetCount(boxacs);
        for (j = 0; j < nrowchars; j++) {
            box = boxaGetBox(boxacs, j, L_COPY);
            if (box->w <= 2 && box->h == 1) {  /* skip 1x1, 2x1 components */
                boxDestroy(&box);
                continue;
            }
            box->y = 0;
            box->h = h - 1;
            pixc = pixClipRectangle(pixr, box, NULL);
            boxDestroy(&box);
            if (i == 0 && j == 0)  /* add a pix for the space; change later */
                pixaAddPix(pixa, pixc, L_COPY);
            if (i == 2 && j == 0)  /* add a pix for the '\'; change later */
                pixaAddPix(pixa, pixc, L_COPY);
            pixaAddPix(pixa, pixc, L_INSERT);
        }
        pixDestroy(&pixr);
        pixDestroy(&pixrc);
        boxaDestroy(&boxac);
        boxaDestroy(&boxacs);
    }
    FREE(tab);

    nchars = pixaGetCount(pixa);
    if (nchars != 95)
        return (PIXA *)ERROR_PTR("95 chars not generated", procName, NULL);

    *pbl0 = baseline[0];
    *pbl1 = baseline[1];
    *pbl2 = baseline[2];

        /* Fix the space character up; it should have no ON pixels,
         * and be about twice as wide as the '!' character.    */
    pix1 = pixaGetPix(pixa, 0, L_CLONE);
    width = 2 * pixGetWidth(pix1);
    height = pixGetHeight(pix1);
    pixDestroy(&pix1);
    pix1 = pixCreate(width, height, 1);
    pixaReplacePix(pixa, 0, pix1, NULL);

        /* Fix up the '\' character; use a LR flip of the '/' char */
    pix1 = pixaGetPix(pixa, 15, L_CLONE);
    pix2 = pixFlipLR(NULL, pix1);
    pixDestroy(&pix1);
    pixaReplacePix(pixa, 60, pix2, NULL);

#if DEBUG_CHARS
    pix1 = pixaDisplayTiled(pixa, 1500, 0, 10);
    pixDisplay(pix1, 100 * i, 200);
    pixDestroy(&pix1);
#endif  /* DEBUG_CHARS */

    boxaDestroy(&boxar);
    return pixa;
}
Beispiel #5
0
int main(int    argc,
         char **argv)
{
char        *dirin, *fileout, *fname, *fullname;
l_int32      depth, width, background, i, nfiles;
l_float32    scale;
SARRAY      *safiles;
PIX         *pix, *pixt, *pixd;
PIXA        *pixa;
static char  mainName[] = "maketile";

    if (argc != 7)
        return ERROR_INT(
            "Syntax:  maketile dirin depth scale width background fileout",
            mainName, 1);

    dirin = argv[1];
    depth = atoi(argv[2]);
    scale = atof(argv[3]);
    width = atoi(argv[4]);
    background = atoi(argv[5]);
    fileout = argv[6];

        /* capture the filenames in the input directory; ignore directories */
    if ((safiles = getFilenamesInDirectory(dirin)) == NULL)
        return ERROR_INT("safiles not made", mainName, 1);

            /* capture images with the requisite depth */
    nfiles = sarrayGetCount(safiles);
    pixa = pixaCreate(nfiles);
    for (i = 0; i < nfiles; i++) {
        fname = sarrayGetString(safiles, i, 0);
        fullname = genPathname(dirin, fname);
        pix = pixRead(fullname);
        lept_free(fullname);
        if (!pix)
            continue;
        if (pixGetDepth(pix) != depth) {
            pixDestroy(&pix);
            continue;
        }
        if (pixGetHeight(pix) > 5000) {
            fprintf(stderr, "%s too tall\n", fname);
            continue;
        }
        pixt = pixScale(pix, scale, scale);
        pixaAddPix(pixa, pixt, L_INSERT);
        pixDestroy(&pix);
/*        fprintf(stderr, "%d..", i); */
    }
    fprintf(stderr, "\n");

        /* tile them */
    pixd = pixaDisplayTiled(pixa, width, background, 15);

    if (depth < 8)
      pixWrite(fileout, pixd, IFF_PNG);
    else
      pixWrite(fileout, pixd, IFF_JFIF_JPEG);

    pixaDestroy(&pixa);
    pixDestroy(&pixd);
    sarrayDestroy(&safiles);
    return 0;
}
Beispiel #6
0
main(int    argc,
     char **argv)
{
l_int32      ws, hs;
BOX         *box;
BOXA        *boxa;
PIX         *pixs, *pixc, *pix32, *pixt, *pixd;
PIXA        *pixat, *pixas, *pixac;
static char  mainName[] = "pixadisp_reg";

    if (argc != 1)
        exit(ERROR_INT(" Syntax: pixadisp_reg", mainName, 1));

    if ((pixs = pixRead("feyn.tif")) == NULL)
        exit(ERROR_INT("pixs not made", mainName, 1));
    box = boxCreate(683, 799, 970, 479);
    pixc = pixClipRectangle(pixs, box, NULL);
    boxDestroy(&box);
    pixDisplayWrite(pixc, 1);
    if ((pix32 = pixRead("marge.jpg")) == NULL)
        exit(ERROR_INT("pix32 not made", mainName, 1));

        /* Generate pixas from pixs and pixac from pixc */
    boxa = pixConnComp(pixs, &pixat, 8);
    pixas = pixaSelectBySize(pixat, 60, 60, L_SELECT_IF_BOTH,
                             L_SELECT_IF_LTE, NULL);
    pixaDestroy(&pixat);
    boxaDestroy(&boxa);
    boxa = pixConnComp(pixc, &pixac, 8);
    boxaDestroy(&boxa);
 
        /* pixaDisplay() */
    pixGetDimensions(pixs, &ws, &hs, NULL);
    pixd = pixaDisplay(pixas, ws, hs);
    pixDisplayWrite(pixd, 1);
    pixDestroy(&pixd);

        /* pixaDisplayRandomCmap() */
    pixd = pixaDisplayRandomCmap(pixas, ws, hs);  /* black bg */
    pixDisplayWrite(pixd, 1);
    pixcmapResetColor(pixGetColormap(pixd), 0, 255, 255, 255);  /* white bg */
    pixDisplayWrite(pixd, 1);
    pixDestroy(&pixd);

        /* pixaDisplayOnLattice() */
    pixd = pixaDisplayOnLattice(pixac, 50, 50);
    pixDisplayWrite(pixd, 1);
    pixDestroy(&pixd);

        /* pixaDisplayUnsplit() */
    pixat = pixaSplitPix(pix32, 5, 7, 10, 0x0000ff00);
    pixd = pixaDisplayUnsplit(pixat, 5, 7, 10, 0x00ff0000);
    pixDisplayWrite(pixd, 1);
    pixaDestroy(&pixat);
    pixDestroy(&pixd);

        /* pixaDisplayTiled() */
    pixd = pixaDisplayTiled(pixac, 1000, 0, 10);
    pixDisplayWrite(pixd, 1);
    pixDestroy(&pixd);

        /* pixaDisplayTiledInRows() */
    pixd = pixaDisplayTiledInRows(pixac, 1, 1000, 1.0, 0, 10, 2);
    pixDisplayWrite(pixd, 1);
    pixDestroy(&pixd);


        /* pixaDisplayTiledAndScaled() */
    pixd = pixaDisplayTiledAndScaled(pixac, 1, 25, 20, 0, 5, 0);
    pixDisplayWrite(pixd, 1);
    pixDestroy(&pixd);

    pixat = pixaCreate(10);
    pixd = pixRankFilter(pix32, 8, 8, 0.5);
    pixaAddPix(pixat, pixd, L_INSERT);
    pixt = pixScale(pix32, 0.5, 0.5);
    pixd = pixRankFilter(pixt, 8, 8, 0.5);
    pixaAddPix(pixat, pixd, L_INSERT);
    pixDestroy(&pixt);
    pixt = pixScale(pix32, 0.25, 0.25);
    pixd = pixRankFilter(pixt, 8, 8, 0.5);
    pixaAddPix(pixat, pixd, L_INSERT);
    pixDestroy(&pixt);
    pixd = pixaDisplayTiledAndScaled(pixat, 32, 500, 1, 0, 25, 0);
    pixDisplayWrite(pixd, 1);
    pixaDestroy(&pixat);
    pixDestroy(&pixd);

    pixaDestroy(&pixas);
    pixaDestroy(&pixac);
    pixDestroy(&pixs);
    pixDestroy(&pixc);
    pixDestroy(&pix32);

    pixDisplayMultiple("/tmp/junk_write_display*");
    return 0;
}
Beispiel #7
0
/*!
 *  pixaGenerateFont()
 *
 *      Input:  dir (directory holding image of character set)
 *              size (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
 *
 *  These font generation functions use 9 sets, each with bitmaps
 *  of 94 ascii characters, all in Palatino-Roman font.
 *  Each input bitmap has 3 rows of characters.  The range of
 *  ascii values in each row is as follows:
 *    row 0:  32-57   (32 is a space)
 *    row 1:  58-91   (92, '\', is not represented in this font)
 *    row 2:  93-126 
 *  We LR flip the '/' char to generate a bitmap for the missing
 *  '\' character, so that we have representations of all 95
 *  printable chars.
 *
 *  Computation of the bitmaps and baselines for a single
 *  font takes from 40 to 200 msec on a 2 GHz processor,
 *  depending on the size.  Use pixaGetFont() to read the
 *  generated character set directly from files that were
 *  produced in prog/genfonts.c using this function.
 */
PIXA *
pixaGenerateFont(const char  *dir,
                 l_int32      size,
                 l_int32     *pbl0,
                 l_int32     *pbl1,
                 l_int32     *pbl2)
{
char     *pathname;
l_int32   fileno;
l_int32   i, j, nrows, nrowchars, nchars, h, yval;
l_int32   width, height;
l_int32   baseline[3];
l_int32  *tab;
BOX      *box, *box1, *box2;
BOXA     *boxar, *boxac, *boxacs;
PIX      *pixs, *pixt1, *pixt2, *pixt3;
PIX      *pixr, *pixrc, *pixc;
PIXA     *pixa;

    PROCNAME("pixaGenerateFont");

    if (!pbl0 || !pbl1 || !pbl2)
        return (PIXA *)ERROR_PTR("&bl not all defined", procName, NULL);
    *pbl0 = *pbl1 = *pbl2 = 0;

    fileno = (size / 2) - 2;
    if (fileno < 0 || fileno > NFONTS)
        return (PIXA *)ERROR_PTR("font size invalid", procName, NULL);
    tab = makePixelSumTab8();
    pathname = genPathname(dir, inputfonts[fileno]);
    if ((pixs = pixRead(pathname)) == NULL)
        return (PIXA *)ERROR_PTR("pixs not all defined", procName, NULL);
    FREE(pathname);

    pixa = pixaCreate(95);
    pixt1 = pixMorphSequence(pixs, "c1.35 + c101.1", 0);
    boxar = pixConnComp(pixt1, NULL, 8);  /* one box for each row */
    pixDestroy(&pixt1);
    nrows = boxaGetCount(boxar);
#if  DEBUG_FONT_GEN
    fprintf(stderr, "For font %s, number of rows is %d\n",
            inputfonts[fileno], nrows);
#endif  /* DEBUG_FONT_GEN */
    if (nrows != 3) {
        L_INFO_INT2("nrows = %d; skipping font %d", procName, nrows, fileno);
        return (PIXA *)ERROR_PTR("3 rows not generated", procName, NULL);
    }
    for (i = 0; i < nrows; i++) {
        box = boxaGetBox(boxar, i, L_CLONE);
        pixr = pixClipRectangle(pixs, box, NULL);  /* row of chars */
        pixGetTextBaseline(pixr, tab, &yval);
        baseline[i] = yval;

#if DEBUG_BASELINE
      { PIX *pixbl;
        fprintf(stderr, "row %d, yval = %d, h = %d\n",
                i, yval, pixGetHeight(pixr));
        pixbl = pixCopy(NULL, pixr);
        pixRenderLine(pixbl, 0, yval, pixGetWidth(pixbl), yval, 1,
                      L_FLIP_PIXELS);
        if (i == 0 )
            pixWrite("junktl0", pixbl, IFF_PNG);
        else if (i == 1)
            pixWrite("junktl1", pixbl, IFF_PNG);
        else
            pixWrite("junktl2", pixbl, IFF_PNG);
        pixDestroy(&pixbl);
      }
#endif  /* DEBUG_BASELINE */

        boxDestroy(&box);
        pixrc = pixCloseSafeBrick(NULL, pixr, 1, 35);
        boxac = pixConnComp(pixrc, NULL, 8);
        boxacs = boxaSort(boxac, L_SORT_BY_X, L_SORT_INCREASING, NULL);
        if (i == 0) {  /* consolidate the two components of '"' */
            box1 = boxaGetBox(boxacs, 1, L_CLONE);
            box2 = boxaGetBox(boxacs, 2, L_CLONE);
            box1->w = box2->x + box2->w - box1->x;  /* increase width */
            boxDestroy(&box1);
            boxDestroy(&box2);
            boxaRemoveBox(boxacs, 2);
        }
        h = pixGetHeight(pixr);
        nrowchars = boxaGetCount(boxacs);
        for (j = 0; j < nrowchars; j++) {
            box = boxaGetBox(boxacs, j, L_COPY);
            if (box->w <= 2 && box->h == 1) {  /* skip 1x1, 2x1 components */
                boxDestroy(&box);
                continue;
            }
            box->y = 0;
            box->h = h - 1;
            pixc = pixClipRectangle(pixr, box, NULL);
            boxDestroy(&box);
            if (i == 0 && j == 0)  /* add a pix for the space; change later */
                pixaAddPix(pixa, pixc, L_COPY);
            if (i == 2 && j == 0)  /* add a pix for the '\'; change later */
                pixaAddPix(pixa, pixc, L_COPY);
            pixaAddPix(pixa, pixc, L_INSERT);
        }
        pixDestroy(&pixr);
        pixDestroy(&pixrc);
        boxaDestroy(&boxac);
        boxaDestroy(&boxacs);
    }

    nchars = pixaGetCount(pixa);
    if (nchars != 95)
        return (PIXA *)ERROR_PTR("95 chars not generated", procName, NULL);

    *pbl0 = baseline[0];
    *pbl1 = baseline[1];
    *pbl2 = baseline[2];
        
        /* Fix the space character up; it should have no ON pixels,
         * and be about twice as wide as the '!' character.    */
    pixt2 = pixaGetPix(pixa, 0, L_CLONE);
    width = 2 * pixGetWidth(pixt2);
    height = pixGetHeight(pixt2);
    pixDestroy(&pixt2);
    pixt2 = pixCreate(width, height, 1);
    pixaReplacePix(pixa, 0, pixt2, NULL);

        /* Fix up the '\' character; use a LR flip of the '/' char */
    pixt2 = pixaGetPix(pixa, 15, L_CLONE);
    pixt3 = pixFlipLR(NULL, pixt2);
    pixDestroy(&pixt2);
    pixaReplacePix(pixa, 60, pixt3, NULL);
    
#if DEBUG_CHARS
  { PIX *pixd;
    pixd = pixaDisplayTiled(pixa, 1500, 0, 10);
    pixDisplay(pixd, 100 * i, 200);
    pixDestroy(&pixd);
  }
#endif  /* DEBUG_CHARS */

    pixDestroy(&pixs);
    boxaDestroy(&boxar);
    FREE(tab);

    return pixa;
}