diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2006-08-19 03:12:28 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2006-08-19 03:12:28 +0000 |
commit | 1fd361a1ea06e44286c213ca1f814f49306fdc43 (patch) | |
tree | 64c8c96cf54d8718847339a403e5e67b922e8c3f /converter/pbm/pbmtoepsi.c | |
download | netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.gz netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.xz netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.zip |
Create Subversion repository
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/pbm/pbmtoepsi.c')
-rw-r--r-- | converter/pbm/pbmtoepsi.c | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/converter/pbm/pbmtoepsi.c b/converter/pbm/pbmtoepsi.c new file mode 100644 index 00000000..fc8cee7d --- /dev/null +++ b/converter/pbm/pbmtoepsi.c @@ -0,0 +1,252 @@ +/* pbmtoepsi.c +** +** by Doug Crabill, based heavily on pbmtoascii +** +** Converts a pbm file to an encapsulated PostScript style bitmap. +** Note that it does NOT covert the pbm file to PostScript, only to +** a bitmap to be added to a piece of PostScript generated elsewhere. +** +** Copyright (C) 1988 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + +#include "pbm.h" +#include "shhopt.h" + +#if !defined(MAXINT) +#define MAXINT (0x7fffffff) +#endif + +struct cmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char *inputFilespec; /* Filespecs of input files */ + + unsigned int dpiX; /* horiz component of DPI option */ + unsigned int dpiY; /* vert component of DPI option */ + unsigned int bbonly; + + unsigned int verbose; +}; + + + +static void +parse_dpi(char * const dpiOpt, + unsigned int * const dpiXP, unsigned int * const dpiYP) { + + char *dpistr2; + unsigned int dpiX, dpiY; + + dpiX = strtol(dpiOpt, &dpistr2, 10); + if (dpistr2 == dpiOpt) + pm_error("Invalid value for -dpi: '%s'. Must be either number " + "or NxN ", dpiOpt); + else { + if (*dpistr2 == '\0') { + *dpiXP = dpiX; + *dpiYP = dpiX; + } else if (*dpistr2 == 'x') { + char * dpistr3; + + dpistr2++; /* Move past 'x' */ + dpiY = strtol(dpistr2, &dpistr3, 10); + if (dpistr3 != dpistr2 && *dpistr3 == '\0') { + *dpiXP = dpiX; + *dpiYP = dpiY; + } else { + pm_error("Invalid value for -dpi: '%s'. Must be either " + "number or NxN", dpiOpt); + } + } + } +} + + +static void +parseCommandLine(int argc, char ** const argv, + struct cmdlineInfo * const cmdlineP) { +/*---------------------------------------------------------------------------- + Note that the file spec array we return is stored in the storage that + was passed to us as the argv array. +-----------------------------------------------------------------------------*/ + optEntry *option_def = malloc(100*sizeof(optEntry)); + /* Instructions to OptParseOptions2 on how to parse our options. + */ + optStruct3 opt; + + unsigned int option_def_index; + + char * dpiOpt; + unsigned int dpiOptSpec; + + option_def_index = 0; /* incremented by OPTENTRY */ + OPTENT3(0, "bbonly", OPT_FLAG, NULL, &cmdlineP->bbonly, 0); + OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); + OPTENT3(0, "dpi", OPT_STRING, &dpiOpt, &dpiOptSpec, 0); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + + optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + + if (dpiOptSpec) + parse_dpi(dpiOpt, &cmdlineP->dpiX, &cmdlineP->dpiY); + else + cmdlineP->dpiX = cmdlineP->dpiY = 72; + + if ((argc-1) > 1) + pm_error("Too many arguments (%d). Only argument is input filespec", + argc-1); + + if (argc-1 == 0) + cmdlineP->inputFilespec = "-"; + else + cmdlineP->inputFilespec = argv[1]; +} + + + +static void +findPrincipalImage(bit ** const bits, + int const rows, + int const cols, + int * const topP, + int * const bottomP, + int * const leftP, + int * const rightP) { + + int top, bottom, left, right; + int row; + + /* Initial values */ + top = MAXINT; + bottom = -MAXINT; + left = MAXINT; + right = -MAXINT; + + for (row = 0; row < rows; row++) { + int col; + for (col = 0; col < cols; col++) { + if (bits[row][col] == PBM_BLACK) { + if (row < top) + top = row; + if (row > bottom) + bottom = row; + if (col < left) + left = col; + if (col > right) + right = col; + } + } + } + *topP = top; + *bottomP = bottom; + *leftP = left; + *rightP = right; +} + + + +static void +outputBoundingBox(int const top, int const bottom, + int const left, int const right, + int const rows, + unsigned int const dpiX, unsigned int const dpiY) { + + float const xScale = 72.0 / dpiX; + float const yScale = 72.0 / dpiY; + + printf("%%%%BoundingBox: %d %d %d %d\n", + ROUND(left*xScale), ROUND((rows - bottom)*yScale), + ROUND(right*xScale), ROUND((rows - top)*yScale)); +} + + + +static unsigned char +eightPixels(bit ** const bits, + int const row, + int const col, + int const cols) { +/*---------------------------------------------------------------------------- + Compute a byte that represents the 8 pixels starting at Column 'col' of + row 'row' of the raster 'bits'. The most significant bit of the result + represents the leftmost pixel, with 1 meaning black. + + The row is 'cols' columns wide, so fill on the right with white if there + are not eight pixels in the row starting with Column 'col'. +-----------------------------------------------------------------------------*/ + unsigned int bitPos; + unsigned char octet; + + octet = 0; /* initial value */ + + for (bitPos = 0; bitPos < 8; ++bitPos) { + octet <<= 1; + if (col + bitPos < cols) + if (bits[row][col + bitPos] == PBM_BLACK) + octet += 1; + } + return(octet); +} + + + +int +main(int argc, char * argv[]) { + + struct cmdlineInfo cmdline; + FILE *ifP; + bit **bits; + int rows, cols; + int top, bottom, left, right; + /* boundaries of principal part of image -- i.e. excluding white + borders + */ + + pbm_init( &argc, argv ); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr(cmdline.inputFilespec); + bits = pbm_readpbm( ifP, &cols, &rows ); + pm_close(ifP); + + findPrincipalImage(bits, rows, cols, &top, &bottom, &left, &right); + + printf("%%!PS-Adobe-2.0 EPSF-1.2\n"); + + outputBoundingBox(top, bottom, left, right, rows, + cmdline.dpiX, cmdline.dpiY); + + if (!cmdline.bbonly) { + int row; + printf("%%%%BeginPreview: %d %d 1 %d\n", + right - left + 1, bottom - top + 1, bottom - top + 1); + + for (row = top; row <= bottom; row++) { + int col; + + printf("%% "); + + for (col = left; col <= right; col += 8) + printf("%02x", eightPixels(bits, row, col, cols)); + + printf("\n"); + } + printf("%%%%EndImage\n"); + printf("%%%%EndPreview\n"); + } + exit(0); +} |