Exemple #1
0
/* leptonica 1.62 doesn't have this function yet, so here it is. */
int fileformat(char *filename){
    FILE *fp;
    int format;
     if ((fp = fopenReadStream(filename)) == NULL)
        return ERROR_INT("image file not found", "fileformat", 1);
#ifdef NEWLEPT
	findFileFormat(filename,&format);
#else
    format=findFileFormat(fp);
#endif
    fclose(fp);
    return format;
}
Exemple #2
0
/*!
 *  pixReadRGBAPng()
 *
 *      Input:  filename (of png file)
 *      Return: pix, or null on error
 *
 *  Notes:
 *      (1) Wrapper to keep the alpha channel of a png, if it exists.
 *      (2) The default behavior of pix read functions is to ignore
 *          the alpha channel.
 *      (3) This always leaves alpha stripping in the same mode as
 *          when this function begins.  So if alpha stripping is in
 *          default mode, this disables it, reads the file (including
 *          the alpha channel), and resets back to stripping.  Otherwise,
 *          it leaves stripping disabled.
 */
PIX *
pixReadRGBAPng(const char  *filename)
{
l_int32  format;
PIX     *pix;

    PROCNAME("pixReadRGBAPng");

    if (!filename)
        return (PIX *)ERROR_PTR("filename not defined", procName, NULL);

        /* Make sure it's a png file */
    findFileFormat(filename, &format);
    if (format != IFF_PNG) {
        L_ERROR_STRING("file format is %s, not png", procName,
                       ImageFileFormatExtensions[format]);
        return NULL;
    }

        /* If alpha channel reading is enabled, just read it */
    if (var_PNG_STRIP_ALPHA == FALSE)
        return pixRead(filename);

    l_pngSetStripAlpha(0);
    pix = pixRead(filename);
    l_pngSetStripAlpha(1);  /* reset to default */
    if (!pix) L_ERROR("pix not read", procName);
    return pix;
}
Exemple #3
0
/*
 *  writeImageCompressedToPSFile()
 *
 *      Input:  filein (input image file)
 *              fileout (output ps file)
 *              res (output printer resolution)
 *              &firstfile (<input and return> 1 if the first image;
 *                          0 otherwise)
 *              &index (<input and return> index of image in output ps file)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This wraps a single page image in PS.
 *      (2) The input file can be in any format.  It is compressed as follows:
 *             * if in tiffg4  -->  use ccittg4
 *             * if in jpeg    -->  use dct
 *             * all others    -->  use flate
 *      (3) @index is incremented if the page is successfully written.
 */
l_int32
writeImageCompressedToPSFile(const char  *filein,
                             const char  *fileout,
                             l_int32      res,
                             l_int32     *pfirstfile,
                             l_int32     *pindex)
{
const char  *op;
l_int32      format, retval;
FILE        *fp;

    PROCNAME("writeImageCompressedToPSFile");

    if (!pfirstfile || !pindex)
        return ERROR_INT("&firstfile and &index not defined", procName, 1);

    if ((fp = fopenReadStream(filein)) == NULL)
        return ERROR_INT("filein not found", procName, 1);
    findFileFormat(fp, &format);
    fclose(fp);
    if (format == IFF_UNKNOWN) {
        L_ERROR_STRING("Format of %s not known", procName, filein);
        return 1;
    }

    op = (*pfirstfile == TRUE) ? "w" : "a";
    if (format == IFF_JFIF_JPEG) {
        retval = convertJpegToPS(filein, fileout, op, 0, 0,
                                 res, 1.0, *pindex + 1, TRUE);
        if (retval == 0) {
            *pfirstfile = FALSE;
            (*pindex)++;
        }
    }
    else if (format == IFF_TIFF_G4) {
        retval = convertTiffG4ToPS(filein, fileout, op, 0, 0,
                                   res, 1.0, *pindex + 1, FALSE, TRUE);
        if (retval == 0) {
            *pfirstfile = FALSE;
            (*pindex)++;
        }
    }
    else {  /* all other image formats */
        retval = convertFlateToPS(filein, fileout, op, 0, 0,
                                  res, 1.0, *pindex + 1, TRUE);
        if (retval == 0) {
            *pfirstfile = FALSE;
            (*pindex)++;
        }
    }

    return retval;
}
/*!
 *  extractJpegDataFromFile()
 *
 *      Input:  filein
 *              &data (<return> binary data consisting of the entire jpeg file)
 *              &nbytes (<return> size of binary data)
 *              &w (<optional return> image width)
 *              &h (<optional return> image height)
 *              &bps (<optional return> bits/sample; should be 8)
 *              &spp (<optional return> samples/pixel; should be 1 or 3)
 *      Return: 0 if OK, 1 on error
 */
l_int32
extractJpegDataFromFile(const char  *filein,
                        l_uint8    **pdata,
                        l_int32     *pnbytes,
                        l_int32     *pw,
                        l_int32     *ph,
                        l_int32     *pbps,
                        l_int32     *pspp)
{
l_uint8  *data;
l_int32   format, nbytes;
FILE     *fpin;

    PROCNAME("extractJpegDataFromFile");

    if (!filein)
        return ERROR_INT("filein not defined", procName, 1);
    if (!pdata)
        return ERROR_INT("&data not defined", procName, 1);
    if (!pnbytes)
        return ERROR_INT("&nbytes not defined", procName, 1);
    if (!pw && !ph && !pbps && !pspp)
        return ERROR_INT("no output data requested", procName, 1);
    *pdata = NULL;
    *pnbytes = 0;

    if ((fpin = fopen(filein, "rb")) == NULL)
        return ERROR_INT("filein not defined", procName, 1);
    findFileFormat(fpin, &format);
    fclose(fpin);
    if (format != IFF_JFIF_JPEG)
        return ERROR_INT("filein not jfif jpeg", procName, 1);

    if ((data = arrayRead(filein, &nbytes)) == NULL)
        return ERROR_INT("inarray not made", procName, 1);
    *pnbytes = nbytes;
    *pdata = data;

        /* On error, free the data */
    if (extractJpegDataFromArray(data, nbytes, pw, ph, pbps, pspp)) {
      FREE(data);
      *pdata = NULL;
      *pnbytes = 0;
    }

    return 0;
}
/*!
 * \brief   l_getIndexFromFile()
 *
 * \param[in]    filename
 * \param[out]   pindex found index
 * \return  0 if found, 1 on error.
 */
static l_int32
l_getIndexFromFile(const char  *filename,
                   l_int32     *pindex)
{
char     buf[256];
char    *word;
FILE    *fp;
l_int32  notfound, format;
SARRAY  *sa;

    PROCNAME("l_getIndexFromFile");

    if (!pindex)
        return ERROR_INT("&index not defined", procName, 1);
    *pindex = 0;
    if (!filename)
        return ERROR_INT("filename not defined", procName, 1);

        /* Open the stream, read lines until you find one with more
         * than a newline, and grab the first word. */
    if ((fp = fopenReadStream(filename)) == NULL)
        return ERROR_INT("stream not opened", procName, 1);
    do {
        if ((fgets(buf, sizeof(buf), fp)) == NULL) {
            fclose(fp);
            return ERROR_INT("fgets read fail", procName, 1);
        }
    } while (buf[0] == '\n');
    fclose(fp);
    sa = sarrayCreateWordsFromString(buf);
    word = sarrayGetString(sa, 0, L_NOCOPY);

        /* Find the index associated with the word.  If it is not
         * found, test to see if the file is a compressed pix. */
    notfound = l_getIndexFromStructname(word, pindex);
    sarrayDestroy(&sa);
    if (notfound) {  /* maybe a Pix */
        if (findFileFormat(filename, &format) == 0) {
            l_getIndexFromStructname("Pix", pindex);
        } else {
            return ERROR_INT("no file type identified", procName, 1);
        }
    }

    return 0;
}
Exemple #6
0
int addGageToRainFile(int i)
//
//  Input:   i = rain gage index
//  Output:  returns 1 if successful, 0 if not
//  Purpose: adds a gage's rainfall record to rain interface file
//
{
    FILE* f;                           // pointer to rain file
    int   fileFormat;                  // file format code
    int   hdrLines;                    // number of header lines skipped

////////////////////////////////////
////  New line added. (LR - 7/5/06 )
////////////////////////////////////
    // --- let StationID point to NULL
    StationID = NULL;

    // --- check that rain file exists
    if ( (f = fopen(Gage[i].fname, "rt")) == NULL )
        report_writeErrorMsg(ERR_RAIN_FILE_DATA, Gage[i].fname);
    else
    {
        fileFormat = findFileFormat(f, i, &hdrLines);
        if ( fileFormat == UNKNOWN_FORMAT )
        {
            report_writeErrorMsg(ERR_RAIN_FILE_FORMAT, Gage[i].fname);
        }
        else
        {
            readFile(f, fileFormat, hdrLines, Gage[i].startFileDate,
                     Gage[i].endFileDate);
        }
        fclose(f);
    }
    if ( ErrorCode ) return 0;
    else
    return 1;
}
Exemple #7
0
/*!
 *  regTestCheckFile()
 *
 *      Input:  rp (regtest parameters)
 *              localname (name of output file from reg test)
 *      Return: 0 if OK, 1 on error (a failure in comparison is not an error)
 *
 *  Notes:
 *      (1) This function does one of three things, depending on the mode:
 *           * "generate": makes a "golden" file as a copy @localname.
 *           * "compare": compares @localname contents with the golden file
 *           * "display": makes the @localname file but does no comparison
 *      (2) The canonical format of the golden filenames is:
 *            /tmp/golden/<root of main name>_golden.<index>.<ext of localname>
 *          e.g.,
 *             /tmp/golden/maze_golden.0.png
 *          It is important to add an extension to the local name, because
 *          the extension is added to the name of the golden file.
 */
l_int32
regTestCheckFile(L_REGPARAMS *rp,
                 const char *localname) {
    char *ext;
    char namebuf[256];
    l_int32 ret, same, format;
    PIX *pix1, *pix2;

    PROCNAME("regTestCheckFile");

    if (!rp)
        return ERROR_INT("rp not defined", procName, 1);
    if (!localname) {
        rp->success = FALSE;
        return ERROR_INT("local name not defined", procName, 1);
    }
    if (rp->mode != L_REG_GENERATE && rp->mode != L_REG_COMPARE &&
        rp->mode != L_REG_DISPLAY) {
        rp->success = FALSE;
        return ERROR_INT("invalid mode", procName, 1);
    }
    rp->index++;

    /* If display mode, no generation and no testing */
    if (rp->mode == L_REG_DISPLAY) return 0;

    /* Generate the golden file name; used in 'generate' and 'compare' */
    splitPathAtExtension(localname, NULL, &ext);
    snprintf(namebuf, sizeof(namebuf), "/tmp/golden/%s_golden.%02d%s",
             rp->testname, rp->index, ext);
    FREE(ext);

    /* Generate mode.  No testing. */
    if (rp->mode == L_REG_GENERATE) {
        /* Save the file as a golden file */
        ret = fileCopy(localname, namebuf);
#if 0       /* Enable for details on writing of golden files */
        if (!ret) {
            char *local = genPathname(localname, NULL);
            char *golden = genPathname(namebuf, NULL);
            L_INFO("Copy: %s to %s\n", procName, local, golden);
            FREE(local);
            FREE(golden);
        }
#endif
        return ret;
    }

    /* Compare mode: test and record on failure.  GIF compression
     * is lossless for images with up to 8 bpp (but not for RGB
     * because it must generate a 256 color palette).  Although
     * the read/write cycle for GIF is idempotent in the image
     * pixels for bpp <= 8, it is not idempotent in the actual
     * file bytes.  Tests comparing file bytes before and after
     * a GIF read/write cycle will fail.  So for GIF we uncompress
     * the two images and compare the actual pixels.  From my tests,
     * PNG, in addition to being lossless, is idempotent in file
     * bytes on read/write, so comparing the pixels is not necessary.
     * (It also increases the regression test time by an an average
     * of about 8%.)  JPEG is lossy and not idempotent in the image
     * pixels, so no tests are constructed that would require it. */
    findFileFormat(localname, &format);
    if (format == IFF_GIF) {
        same = 0;
        pix1 = pixRead(localname);
        pix2 = pixRead(namebuf);
        pixEqual(pix1, pix2, &same);
        pixDestroy(&pix1);
        pixDestroy(&pix2);
    } else {
        filesAreIdentical(localname, namebuf, &same);
    }
    if (!same) {
        fprintf(rp->fp, "Failure in %s_reg, index %d: comparing %s with %s\n",
                rp->testname, rp->index, localname, namebuf);
        fprintf(stderr, "Failure in %s_reg, index %d: comparing %s with %s\n",
                rp->testname, rp->index, localname, namebuf);
        rp->success = FALSE;
    }

    return 0;
}
bool TessPDFRenderer::imageToPDFObj(Pix *pix,
                                    char *filename,
                                    long int objnum,
                                    char **pdf_object,
                                    long int *pdf_object_size) {
    size_t n;
    char b0[kBasicBufSize];
    char b1[kBasicBufSize];
    char b2[kBasicBufSize];
    if (!pdf_object_size || !pdf_object)
        return false;
    *pdf_object = NULL;
    *pdf_object_size = 0;
    if (!filename)
        return false;

    L_COMP_DATA *cid = NULL;
    const int kJpegQuality = 85;

    // TODO(jbreiden) Leptonica 1.71 doesn't correctly handle certain
    // types of PNG files, especially if there are 2 samples per pixel.
    // We can get rid of this logic after Leptonica 1.72 is released and
    // has propagated everywhere. Bug discussion as follows.
    // https://code.google.com/p/tesseract-ocr/issues/detail?id=1300
    int format, sad;
    findFileFormat(filename, &format);
    if (pixGetSpp(pix) == 4 && format == IFF_PNG) {
        pixSetSpp(pix, 3);
        sad = pixGenerateCIData(pix, L_FLATE_ENCODE, 0, 0, &cid);
    } else {
        sad = l_generateCIDataForPdf(filename, pix, kJpegQuality, &cid);
    }

    if (sad || !cid) {
        l_CIDataDestroy(&cid);
        return false;
    }

    const char *group4 = "";
    const char *filter;
    switch (cid->type) {
    case L_FLATE_ENCODE:
        filter = "/FlateDecode";
        break;
    case L_JPEG_ENCODE:
        filter = "/DCTDecode";
        break;
    case L_G4_ENCODE:
        filter = "/CCITTFaxDecode";
        group4 = "    /K -1\n";
        break;
    case L_JP2K_ENCODE:
        filter = "/JPXDecode";
        break;
    default:
        l_CIDataDestroy(&cid);
        return false;
    }

    // Maybe someday we will accept RGBA but today is not that day.
    // It requires creating an /SMask for the alpha channel.
    // http://stackoverflow.com/questions/14220221
    const char *colorspace;
    if (cid->ncolors > 0) {
        n = snprintf(b0, sizeof(b0),
                     "  /ColorSpace [ /Indexed /DeviceRGB %d %s ]\n",
                     cid->ncolors - 1, cid->cmapdatahex);
        if (n >= sizeof(b0)) {
            l_CIDataDestroy(&cid);
            return false;
        }
        colorspace = b0;
    } else {
        switch (cid->spp) {
        case 1:
            colorspace = "  /ColorSpace /DeviceGray\n";
            break;
        case 3:
            colorspace = "  /ColorSpace /DeviceRGB\n";
            break;
        default:
            l_CIDataDestroy(&cid);
            return false;
        }
    }

    int predictor = (cid->predictor) ? 14 : 1;

    // IMAGE
    n = snprintf(b1, sizeof(b1),
                 "%ld 0 obj\n"
                 "<<\n"
                 "  /Length %ld\n"
                 "  /Subtype /Image\n",
                 objnum, (unsigned long) cid->nbytescomp);
    if (n >= sizeof(b1)) {
        l_CIDataDestroy(&cid);
        return false;
    }

    n = snprintf(b2, sizeof(b2),
                 "  /Width %d\n"
                 "  /Height %d\n"
                 "  /BitsPerComponent %d\n"
                 "  /Filter %s\n"
                 "  /DecodeParms\n"
                 "  <<\n"
                 "    /Predictor %d\n"
                 "    /Colors %d\n"
                 "%s"
                 "    /Columns %d\n"
                 "    /BitsPerComponent %d\n"
                 "  >>\n"
                 ">>\n"
                 "stream\n",
                 cid->w, cid->h, cid->bps, filter, predictor, cid->spp,
                 group4, cid->w, cid->bps);
    if (n >= sizeof(b2)) {
        l_CIDataDestroy(&cid);
        return false;
    }

    const char *b3 =
        "endstream\n"
        "endobj\n";

    size_t b1_len = strlen(b1);
    size_t b2_len = strlen(b2);
    size_t b3_len = strlen(b3);
    size_t colorspace_len = strlen(colorspace);

    *pdf_object_size =
        b1_len + colorspace_len + b2_len + cid->nbytescomp + b3_len;
    *pdf_object = new char[*pdf_object_size];
    if (!pdf_object) {
        l_CIDataDestroy(&cid);
        return false;
    }

    char *p = *pdf_object;
    memcpy(p, b1, b1_len);
    p += b1_len;
    memcpy(p, colorspace, colorspace_len);
    p += colorspace_len;
    memcpy(p, b2, b2_len);
    p += b2_len;
    memcpy(p, cid->datacomp, cid->nbytescomp);
    p += cid->nbytescomp;
    memcpy(p, b3, b3_len);
    l_CIDataDestroy(&cid);
    return true;
}
Exemple #9
0
/*
 *  convertToPSEmbed()
 *
 *      Input:  filein (input image file -- any format)
 *              fileout (output ps file)
 *              level (compression: 1 (uncompressed), 2 or 3)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This is a wrapper function that generates a PS file with
 *          a bounding box, from any input image file.
 *      (2) Do the best job of compression given the specified level.
 *          @level=3 does flate compression on anything that is not
 *          tiffg4 (1 bpp) or jpeg (8 bpp or rgb).
 *      (3) If @level=2 and the file is not tiffg4 or jpeg, it will
 *          first be written to file as jpeg with quality = 75.
 *          This will remove the colormap and cause some degradation
 *          in the image.
 *      (4) The bounding box is required when a program such as TeX
 *          (through epsf) places and rescales the image.  It is
 *          sized for fitting the image to an 8.5 x 11.0 inch page.
 */
l_int32
convertToPSEmbed(const char  *filein,
                 const char  *fileout,
                 l_int32      level)
{
const char  nametif[] = "/tmp/junk_convert_ps_embed.tif";
const char  namejpg[] = "/tmp/junk_convert_ps_embed.jpg";
l_int32     d, format;
FILE       *fp;
PIX        *pix, *pixs;

    PROCNAME("convertToPSEmbed");

    if (!filein)
        return ERROR_INT("filein not defined", procName, 1);
    if (!fileout)
        return ERROR_INT("fileout not defined", procName, 1);
    if (level != 1 && level != 2 && level != 3) {
        L_ERROR("invalid level specified; using level 2", procName);
        level = 2;
    }

    if (level == 1) {  /* no compression */
        pixWritePSEmbed(filein, fileout);
        return 0;
    }

        /* Find the format and write out directly if in jpeg or tiff g4 */
    if ((fp = fopen(filein, "rb")) == NULL)
        return ERROR_INT("filein not found", procName, 1);
    findFileFormat(fp, &format);
    fclose(fp);
    if (format == IFF_JFIF_JPEG) {
        convertJpegToPSEmbed(filein, fileout);
        return 0;
    }
    else if (format == IFF_TIFF_G4) {
        convertTiffG4ToPSEmbed(filein, fileout);
        return 0;
    }

        /* If level 3, flate encode. */
    if (level == 3) {
        convertFlateToPSEmbed(filein, fileout);
        return 0;
    }

        /* OK, it's level 2, so we must convert to jpeg or tiff g4 */
    if ((pixs = pixRead(filein)) == NULL)
        return ERROR_INT("image not read from file", procName, 1);
    d = pixGetDepth(pixs);
    if ((d == 2 || d == 4) && !pixGetColormap(pixs))
        pix = pixConvertTo8(pixs, 0);
    else if (d == 16)
        pix = pixConvert16To8(pixs, 1);
    else
        pix = pixRemoveColormap(pixs, REMOVE_CMAP_BASED_ON_SRC);

    d = pixGetDepth(pix);
    if (d == 1) {
        pixWrite(nametif, pix, IFF_TIFF_G4);
        convertTiffG4ToPSEmbed(nametif, fileout);
    }
    else {
        pixWrite(namejpg, pix, IFF_JFIF_JPEG);
        convertJpegToPSEmbed(namejpg, fileout);
    }

    pixDestroy(&pix);
    pixDestroy(&pixs);
    return 0;
}
Exemple #10
0
bool TessPDFRenderer::imageToPDFObj(Pix *pix,
                                    char *filename,
                                    long int objnum,
                                    char **pdf_object,
                                    long int *pdf_object_size) {
  size_t n;
  char b0[kBasicBufSize];
  char b1[kBasicBufSize];
  char b2[kBasicBufSize];
  if (!pdf_object_size || !pdf_object)
    return false;
  *pdf_object = nullptr;
  *pdf_object_size = 0;
  if (!filename)
    return false;

  L_Compressed_Data *cid = nullptr;
  const int kJpegQuality = 85;

  int format, sad;
  findFileFormat(filename, &format);
  if (pixGetSpp(pix) == 4 && format == IFF_PNG) {
    Pix *p1 = pixAlphaBlendUniform(pix, 0xffffff00);
    sad = pixGenerateCIData(p1, L_FLATE_ENCODE, 0, 0, &cid);
    pixDestroy(&p1);
  } else {
    sad = l_generateCIDataForPdf(filename, pix, kJpegQuality, &cid);
  }

  if (sad || !cid) {
    l_CIDataDestroy(&cid);
    return false;
  }

  const char *group4 = "";
  const char *filter;
  switch(cid->type) {
    case L_FLATE_ENCODE:
      filter = "/FlateDecode";
      break;
    case L_JPEG_ENCODE:
      filter = "/DCTDecode";
      break;
    case L_G4_ENCODE:
      filter = "/CCITTFaxDecode";
      group4 = "    /K -1\n";
      break;
    case L_JP2K_ENCODE:
      filter = "/JPXDecode";
      break;
    default:
      l_CIDataDestroy(&cid);
      return false;
  }

  // Maybe someday we will accept RGBA but today is not that day.
  // It requires creating an /SMask for the alpha channel.
  // http://stackoverflow.com/questions/14220221
  const char *colorspace;
  if (cid->ncolors > 0) {
    n = snprintf(b0, sizeof(b0),
                 "  /ColorSpace [ /Indexed /DeviceRGB %d %s ]\n",
                 cid->ncolors - 1, cid->cmapdatahex);
    if (n >= sizeof(b0)) {
      l_CIDataDestroy(&cid);
      return false;
    }
    colorspace = b0;
  } else {
    switch (cid->spp) {
      case 1:
        colorspace = "  /ColorSpace /DeviceGray\n";
        break;
      case 3:
        colorspace = "  /ColorSpace /DeviceRGB\n";
        break;
      default:
        l_CIDataDestroy(&cid);
        return false;
    }
  }

  int predictor = (cid->predictor) ? 14 : 1;

  // IMAGE
  n = snprintf(b1, sizeof(b1),
               "%ld 0 obj\n"
               "<<\n"
               "  /Length %ld\n"
               "  /Subtype /Image\n",
               objnum, (unsigned long) cid->nbytescomp);
  if (n >= sizeof(b1)) {
    l_CIDataDestroy(&cid);
    return false;
  }

  n = snprintf(b2, sizeof(b2),
               "  /Width %d\n"
               "  /Height %d\n"
               "  /BitsPerComponent %d\n"
               "  /Filter %s\n"
               "  /DecodeParms\n"
               "  <<\n"
               "    /Predictor %d\n"
               "    /Colors %d\n"
               "%s"
               "    /Columns %d\n"
               "    /BitsPerComponent %d\n"
               "  >>\n"
               ">>\n"
               "stream\n",
               cid->w, cid->h, cid->bps, filter, predictor, cid->spp,
               group4, cid->w, cid->bps);
  if (n >= sizeof(b2)) {
    l_CIDataDestroy(&cid);
    return false;
  }

  const char *b3 =
      "endstream\n"
      "endobj\n";

  size_t b1_len = strlen(b1);
  size_t b2_len = strlen(b2);
  size_t b3_len = strlen(b3);
  size_t colorspace_len = strlen(colorspace);

  *pdf_object_size =
      b1_len + colorspace_len + b2_len + cid->nbytescomp + b3_len;
  *pdf_object = new char[*pdf_object_size];

  char *p = *pdf_object;
  memcpy(p, b1, b1_len);
  p += b1_len;
  memcpy(p, colorspace, colorspace_len);
  p += colorspace_len;
  memcpy(p, b2, b2_len);
  p += b2_len;
  memcpy(p, cid->datacomp, cid->nbytescomp);
  p += cid->nbytescomp;
  memcpy(p, b3, b3_len);
  l_CIDataDestroy(&cid);
  return true;
}
Exemple #11
0
/*
 *  convertToPSEmbed()
 *
 *      Input:  filein (input image file -- any format)
 *              fileout (output ps file)
 *              level (compression: 1 (uncompressed), 2 or 3)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This is a wrapper function that generates a PS file with
 *          a bounding box, from any input image file.
 *      (2) Do the best job of compression given the specified level.
 *          %level=3 does flate compression on anything that is not
 *          tiffg4 (1 bpp) or jpeg (8 bpp or rgb).
 *      (3) If %level=2 and the file is not tiffg4 or jpeg, it will
 *          first be written to file as jpeg with quality = 75.
 *          This will remove the colormap and cause some degradation
 *          in the image.
 *      (4) The bounding box is required when a program such as TeX
 *          (through epsf) places and rescales the image.  It is
 *          sized for fitting the image to an 8.5 x 11.0 inch page.
 */
l_int32
convertToPSEmbed(const char  *filein,
                 const char  *fileout,
                 l_int32      level)
{
    char    *tname;
    l_int32  d, format;
    PIX     *pix, *pixs;

    PROCNAME("convertToPSEmbed");

    if (!filein)
        return ERROR_INT("filein not defined", procName, 1);
    if (!fileout)
        return ERROR_INT("fileout not defined", procName, 1);
    if (level != 1 && level != 2 && level != 3) {
        L_ERROR("invalid level specified; using level 2\n", procName);
        level = 2;
    }

    if (level == 1) {  /* no compression */
        pixWritePSEmbed(filein, fileout);
        return 0;
    }

    /* Find the format and write out directly if in jpeg or tiff g4 */
    findFileFormat(filein, &format);
    if (format == IFF_JFIF_JPEG) {
        convertJpegToPSEmbed(filein, fileout);
        return 0;
    } else if (format == IFF_TIFF_G4) {
        convertG4ToPSEmbed(filein, fileout);
        return 0;
    } else if (format == IFF_UNKNOWN) {
        L_ERROR("format of %s not known\n", procName, filein);
        return 1;
    }

    /* If level 3, flate encode. */
    if (level == 3) {
        convertFlateToPSEmbed(filein, fileout);
        return 0;
    }

    /* OK, it's level 2, so we must convert to jpeg or tiff g4 */
    if ((pixs = pixRead(filein)) == NULL)
        return ERROR_INT("image not read from file", procName, 1);
    d = pixGetDepth(pixs);
    if ((d == 2 || d == 4) && !pixGetColormap(pixs))
        pix = pixConvertTo8(pixs, 0);
    else if (d == 16)
        pix = pixConvert16To8(pixs, 1);
    else
        pix = pixRemoveColormap(pixs, REMOVE_CMAP_BASED_ON_SRC);

    d = pixGetDepth(pix);
    tname = l_makeTempFilename(NULL);
    if (d == 1) {
        pixWrite(tname, pix, IFF_TIFF_G4);
        convertG4ToPSEmbed(tname, fileout);
    } else {
        pixWrite(tname, pix, IFF_JFIF_JPEG);
        convertJpegToPSEmbed(tname, fileout);
    }

    lept_rmfile(tname);
    LEPT_FREE(tname);
    pixDestroy(&pix);
    pixDestroy(&pixs);
    return 0;
}