diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2011-12-30 18:13:51 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2011-12-30 18:13:51 +0000 |
commit | 88bc10b9a5a923870eab79627b86e5d7318a0a91 (patch) | |
tree | 8cc51ec1d341a5820ae071f08b01e1a5a572a442 | |
parent | 07907eea94e6d1c66e2128127f6e90cc5204719b (diff) | |
parent | 960fff9ac6846c446a1fdaf85d8e57c53f28c9c3 (diff) | |
download | netpbm-mirror-88bc10b9a5a923870eab79627b86e5d7318a0a91.tar.gz netpbm-mirror-88bc10b9a5a923870eab79627b86e5d7318a0a91.tar.xz netpbm-mirror-88bc10b9a5a923870eab79627b86e5d7318a0a91.zip |
Merge current Development branch to become Release 10.57.00
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@1614 9d0c8265-081b-0410-96cb-a4ca84ce46f8
65 files changed, 794 insertions, 244 deletions
diff --git a/common.mk b/common.mk index 831619fa..01fb6d91 100644 --- a/common.mk +++ b/common.mk @@ -132,7 +132,8 @@ IMPORTINC_LIB_HEADERS := \ pm_gamma.h lum.h dithers.h pamdraw.h IMPORTINC_LIB_UTIL_HEADERS := \ - bitarith.h bitreverse.h filename.h intcode.h floatcode.h io.h mallocvar.h\ + bitarith.h bitreverse.h filename.h intcode.h floatcode.h io.h \ + matrix.h mallocvar.h \ nsleep.h nstring.h pm_c_util.h shhopt.h token.h \ wordaccess.h wordaccess_64_le.h wordaccess_gcc3_be.h wordaccess_generic.h \ wordintclz.h diff --git a/converter/other/fiasco/codec/approx.c b/converter/other/fiasco/codec/approx.c index 72e38cbf..5072fae3 100644 --- a/converter/other/fiasco/codec/approx.c +++ b/converter/other/fiasco/codec/approx.c @@ -294,7 +294,7 @@ static real_t ip_domain_ortho_vector [MAXSTATES][MAXEDGES]; static real_t rem_denominator [MAXSTATES]; static real_t rem_numerator [MAXSTATES]; /* - * At step n of the orthogonalization the comparitive value + * At step n of the orthogonalization the comparative value * (numerator_i / denominator_i):= <b, o_n>^2 / ||o_n|| , * is computed for every domain i, * where o_n := s_i - \sum(k = 0, ... , n-1) {(<s_i, o_k> / ||o_k||^2) o_k} @@ -670,7 +670,7 @@ orthogonalize (unsigned index, unsigned n, unsigned level, real_t min_norm, * for (i = 0, ... , wfa->states) * <s_i, o_n> := <s_i, v_n> - * \sum (k = 0, ... , n - 1){ <v_n, o_k> <s_i, o_k> / ||o_k||^2} - * Moreover the denominator and numerator parts of the comparitive + * Moreover the denominator and numerator parts of the comparative * value are updated. */ for (domain = 0; domain_blocks [domain] >= 0; domain++) diff --git a/converter/other/fiasco/codec/subdivide.c b/converter/other/fiasco/codec/subdivide.c index f845d859..059aa477 100644 --- a/converter/other/fiasco/codec/subdivide.c +++ b/converter/other/fiasco/codec/subdivide.c @@ -289,7 +289,7 @@ subdivide (real_t max_costs, unsigned band, int y_state, range_t *range, : rrange.y; /* - * If neccessary compute the inner products of the new states + * If necessary compute the inner products of the new states * (generated during the recursive approximation of child [0]) */ if (label && rrange.level <= c->options.lc_max_level) diff --git a/converter/other/fiasco/codec/wfa.h b/converter/other/fiasco/codec/wfa.h index 8b9793f2..0b96ba8c 100644 --- a/converter/other/fiasco/codec/wfa.h +++ b/converter/other/fiasco/codec/wfa.h @@ -122,7 +122,7 @@ typedef struct wfa real_t *final_distribution; /* one pixel images */ byte_t *level_of_state; /* level of the image part which is represented by the current state */ - byte_t *domain_type; /* Bit_0==1: auxilliary state + byte_t *domain_type; /* Bit_0==1: auxiliary state Bit_1==1: used for Y compr */ mv_t (*mv_tree)[MAXLABELS]; /* motion vectors */ word_t (*tree)[MAXLABELS]; /* bintree partitioning */ diff --git a/converter/other/fiasco/input/read.c b/converter/other/fiasco/input/read.c index 23f92070..9690a6c5 100644 --- a/converter/other/fiasco/input/read.c +++ b/converter/other/fiasco/input/read.c @@ -277,7 +277,7 @@ read_basis (const char *filename, wfa_t *wfa) * string |MAGIC Number "Wfa" * int |Number of basis states 'N' * bool_t-array[N] |use vector in linear combinations, - * |0: don't use vector (auxilliary state) + * |0: don't use vector (auxiliary state) * |1: use vector in linear combinations * float-array[N] |final distribution of every state * diff --git a/converter/other/fiasco/lib/arith.c b/converter/other/fiasco/lib/arith.c index e3745bf7..dc35d1d1 100644 --- a/converter/other/fiasco/lib/arith.c +++ b/converter/other/fiasco/lib/arith.c @@ -90,7 +90,7 @@ encode_symbol (unsigned symbol, arith_t *arith, model_t *model) * The current state of the arithmetic coder is given by 'arith'. * Output bits are appended to the stream 'output'. * - * The model is updated after encoding the symbol (if neccessary the + * The model is updated after encoding the symbol (if necessary the * symbol counts are rescaled). * * Return value: @@ -354,7 +354,7 @@ decode_symbol (arith_t *arith, model_t *model) * Decode the next symbol - the state of the arithmetic decoder * is given in 'arith'. Read refinement bits from the stream 'input' * and use the given probability 'model'. Update the probability model after - * deconding the symbol (if neccessary also rescale the symbol counts). + * deconding the symbol (if necessary also rescale the symbol counts). * * Return value: * decoded symbol diff --git a/converter/other/fiasco/lib/misc.c b/converter/other/fiasco/lib/misc.c index e0e41447..dd9f0bb2 100644 --- a/converter/other/fiasco/lib/misc.c +++ b/converter/other/fiasco/lib/misc.c @@ -1,5 +1,5 @@ /* - * misc.c: Some usefull functions, that don't fit in one of + * misc.c: Some useful functions, that don't fit in one of * the other files and that are needed by at least * two modules. * diff --git a/converter/other/infotopam.c b/converter/other/infotopam.c index 0504a147..f2e35827 100644 --- a/converter/other/infotopam.c +++ b/converter/other/infotopam.c @@ -114,7 +114,7 @@ typedef struct DiskObject_ { /* 78 bytes (including Gadget struct) */ unsigned char version[2]; /* Object version number */ unsigned char gadget[44]; /* Copy of in memory gadget (44 by */ unsigned char type; /* ??? */ - unsigned char pad; /* Pad it out to the next word boundry */ + unsigned char pad; /* Pad it out to the next word boundary */ unsigned char pDefaultTool[4]; /* Pointer to default tool */ unsigned char ppToolTypes[4]; /* Pointer pointer to tool types */ unsigned char currentX[4]; /* Current X position (?) */ diff --git a/converter/other/jbig/jbig.c b/converter/other/jbig/jbig.c index ebd7c08f..90295d8b 100644 --- a/converter/other/jbig/jbig.c +++ b/converter/other/jbig/jbig.c @@ -2330,7 +2330,7 @@ static size_t decode_pscd(struct jbg_dec_state *s, unsigned char *data, * cases the remaining len - *cnt bytes of the previous block will * have to passed to this function again (if len > *cnt). In case of * any other return value than JBG_EOK, JBG_EOK_INTR or JBG_EAGAIN, a - * serious problem has occured and the only function you should call + * serious problem has occurred and the only function you should call * is jbg_dec_free() in order to remove the mess (and probably * jbg_strerror() in order to find out what to tell the user). */ diff --git a/converter/other/jpeg2000/libjasper/base/jas_stream.c b/converter/other/jpeg2000/libjasper/base/jas_stream.c index 19dc7c11..7af161d2 100644 --- a/converter/other/jpeg2000/libjasper/base/jas_stream.c +++ b/converter/other/jpeg2000/libjasper/base/jas_stream.c @@ -902,7 +902,7 @@ int jas_stream_copy(jas_stream_t *out, jas_stream_t *in, int n) while (all || m > 0) { if ((c = jas_stream_getc_macro(in)) == EOF) { /* The next character of input could not be read. */ - /* Return with an error if an I/O error occured + /* Return with an error if an I/O error occurred (not including EOF) or if an explicit copy count was specified. */ return (!all || jas_stream_error(in)) ? (-1) : 0; diff --git a/converter/other/jpeg2000/libjasper/jpc/jpc_bs.h b/converter/other/jpeg2000/libjasper/jpc/jpc_bs.h index f515972b..edb0a2df 100644 --- a/converter/other/jpeg2000/libjasper/jpc/jpc_bs.h +++ b/converter/other/jpeg2000/libjasper/jpc/jpc_bs.h @@ -149,7 +149,7 @@ #define JPC_BITSTREAM_NOCLOSE 0x01 /* End of file has been reached while reading. */ #define JPC_BITSTREAM_EOF 0x02 -/* An I/O error has occured. */ +/* An I/O error has occurred. */ #define JPC_BITSTREAM_ERR 0x04 /******************************************************************************\ diff --git a/converter/other/jpeg2000/libjasper/jpc/jpc_cs.h b/converter/other/jpeg2000/libjasper/jpc/jpc_cs.h index 07a046d1..4bff677c 100644 --- a/converter/other/jpeg2000/libjasper/jpc/jpc_cs.h +++ b/converter/other/jpeg2000/libjasper/jpc/jpc_cs.h @@ -188,7 +188,7 @@ typedef struct { /* The tile number. */ uint_fast16_t tileno; - /* The combined length of the marker segment and its auxilary data + /* The combined length of the marker segment and its auxiliary data (i.e., packet data). */ uint_fast32_t len; diff --git a/converter/other/jpeg2000/libjasper/jpc/jpc_dec.h b/converter/other/jpeg2000/libjasper/jpc/jpc_dec.h index 5231048d..02c5553d 100644 --- a/converter/other/jpeg2000/libjasper/jpc/jpc_dec.h +++ b/converter/other/jpeg2000/libjasper/jpc/jpc_dec.h @@ -175,7 +175,7 @@ typedef struct { /* The number of streams in this list. */ int numstreams; - /* The maximum number of streams that can be accomodated without + /* The maximum number of streams that can be accommodated without growing the streams array. */ int maxstreams; diff --git a/converter/other/jpeg2000/libjasper/jpc/jpc_t2cod.h b/converter/other/jpeg2000/libjasper/jpc/jpc_t2cod.h index 05f41b9e..82dafcce 100644 --- a/converter/other/jpeg2000/libjasper/jpc/jpc_t2cod.h +++ b/converter/other/jpeg2000/libjasper/jpc/jpc_t2cod.h @@ -136,7 +136,7 @@ typedef struct { /* The number of progression changes. */ int numpchgs; - /* The maximum number of progression changes that can be accomodated + /* The maximum number of progression changes that can be accommodated without growing the progression change array. */ int maxpchgs; @@ -253,7 +253,7 @@ typedef struct { /* The progression change list. */ jpc_pchglist_t *pchglist; - /* The progression to use in the absense of explicit specification. */ + /* The progression to use in the absence of explicit specification. */ jpc_pchg_t defaultpchg; /* The current progression change number. */ diff --git a/converter/other/jpegtopnm.c b/converter/other/jpegtopnm.c index 790abff2..cbac0a09 100644 --- a/converter/other/jpegtopnm.c +++ b/converter/other/jpegtopnm.c @@ -22,7 +22,7 @@ Extend pamtoppm to convert this to ppm using the standard transformation. - See if additional decompressor options effects signficant speedup. + See if additional decompressor options effects significant speedup. grayscale output of color image, downscaling, color quantization, and dithering are possibilities. Djpeg's man page says they make it faster. diff --git a/converter/other/pamtopnm.c b/converter/other/pamtopnm.c index 8bb45192..ba655b1e 100644 --- a/converter/other/pamtopnm.c +++ b/converter/other/pamtopnm.c @@ -69,11 +69,11 @@ validateTupleType(struct pam const inpam, /*---------------------------------------------------------------------------- Make sure the image has a tuple type we know how to convert to PNM. - We're quite liberal, trying to accomodate all sorts of future + We're quite liberal, trying to accommodate all sorts of future twists on the formats. If the tuple type _starts with_ BLACKANDWHITE, GRAYSCALE, or RGB, and has at least as many planes as we'd need to convert to PBM, PGM, or PPM, respectively, we - accept it. We thus accomodate variations on these formats that add + accept it. We thus accommodate variations on these formats that add planes and add to the right end of the tuple type to explain them. If Callers specified 'assumeTupleType', we're even more liberal. diff --git a/converter/other/pnmtopng.c b/converter/other/pnmtopng.c index 4b18bdf3..3e41e64d 100644 --- a/converter/other/pnmtopng.c +++ b/converter/other/pnmtopng.c @@ -1643,7 +1643,7 @@ makeOneColorTransparentInPalette(xel const transColor, *transSizeP = 1; if (verbose) { pixel const p = palette_pnm[0]; - pm_message("Making all occurences of color (%u, %u, %u) " + pm_message("Making all occurrences of color (%u, %u, %u) " "transparent.", PPM_GETR(p), PPM_GETG(p), PPM_GETB(p)); } diff --git a/converter/other/sunicontopnm.c b/converter/other/sunicontopnm.c index 005b4491..ad5aa0f8 100644 --- a/converter/other/sunicontopnm.c +++ b/converter/other/sunicontopnm.c @@ -13,7 +13,7 @@ /* Most icon images are monochrome: Depth=1 Depth=8 images are extremely rare. At least some of these are color - images but we can't tell the pallete color order. + images but we can't tell the palette color order. Output will be in pgm. Convert to ppm with pgmtoppm or pamlookup if necessary. */ diff --git a/converter/other/xwdtopnm.c b/converter/other/xwdtopnm.c index f96b2fe4..d49a2b09 100644 --- a/converter/other/xwdtopnm.c +++ b/converter/other/xwdtopnm.c @@ -837,7 +837,7 @@ typedef struct { 'nBitsLeft' tells how many bits are in the buffer now. It's zero when nothing has ever been read from the file. Only - the least signficant 'nBitsLeft' bits are meaningful. + the least significant 'nBitsLeft' bits are meaningful. The numeric value of the member is the number whose pure binary representation is the bit string in the buffer. @@ -974,7 +974,7 @@ readItem(pixelReader * const rdrP) { static unsigned long const lsbmask[] = { /*---------------------------------------------------------------------------- - lsbmask[i] is the mask you use to select the i least signficant bits + lsbmask[i] is the mask you use to select the i least significant bits of a bit string. -----------------------------------------------------------------------------*/ 0x00000000, diff --git a/converter/pbm/pbmtolj.c b/converter/pbm/pbmtolj.c index 4afa4c6d..89dcb76c 100644 --- a/converter/pbm/pbmtolj.c +++ b/converter/pbm/pbmtolj.c @@ -162,7 +162,7 @@ putinit(struct cmdlineInfo const cmdline) { /* Set raster graphics resolution */ printf("\033*t%dR", cmdline.dpi); - /* Start raster graphics, relative adressing */ + /* Start raster graphics, relative addressing */ printf("\033*r1A"); bitsperitem = 1; diff --git a/converter/ppm/ilbmtoppm.c b/converter/ppm/ilbmtoppm.c index a1aae7f4..a898d705 100644 --- a/converter/ppm/ilbmtoppm.c +++ b/converter/ppm/ilbmtoppm.c @@ -9,7 +9,7 @@ ** documentation. This software is provided "as is" without express or ** implied warranty. ** -** Modified by Mark Thompson on 10/4/90 to accomodate 24-bit IFF files +** Modified by Mark Thompson on 10/4/90 to accommodate 24-bit IFF files ** as used by ASDG, NewTek, etc. ** ** Modified by Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) diff --git a/converter/ppm/pc1toppm.c b/converter/ppm/pc1toppm.c index 5ba247e9..ec6678a4 100644 --- a/converter/ppm/pc1toppm.c +++ b/converter/ppm/pc1toppm.c @@ -170,7 +170,7 @@ writePpm(FILE * const ofP, is represented by 4 shorts (16 bit integers). The first is for Plane 0, the second for Plane 1, etc. Each short contains the bits for that plane for each of the 16 columns, - arranged from most signficant bit to least in increasing column + arranged from most significant bit to least in increasing column number. */ unsigned int col0ScreenIndex = cols/16*planes * row; diff --git a/converter/ppm/pcxtoppm.c b/converter/ppm/pcxtoppm.c index b6369806..8b8ee7d5 100644 --- a/converter/ppm/pcxtoppm.c +++ b/converter/ppm/pcxtoppm.c @@ -539,7 +539,7 @@ pcx_256col_to_ppm(FILE * const ifP, /* * 256 color images have their color map at the end of the file - * preceeded by a magic byte + * preceded by a magic byte */ colormapSignature = GetByte(ifP); if (colormapSignature != PCX_256_COLORS) diff --git a/converter/ppm/picttoppm.c b/converter/ppm/picttoppm.c index f3c9ffb0..43b8d1ef 100644 --- a/converter/ppm/picttoppm.c +++ b/converter/ppm/picttoppm.c @@ -2543,7 +2543,7 @@ interpretCompressedLine(unsigned char * const linebuf, So with 200 being the cutoff, it's actually impossible to represent some 16 bpp images with 200 pixels per row. - We have not been able to find an offical spec for PICT. + We have not been able to find an official spec for PICT. Some day, we may have to make a user option for this. */ @@ -3191,7 +3191,7 @@ frameSameRect(struct canvas * const canvasP, -/* a stupid shell sort - I'm so embarassed */ +/* a stupid shell sort - I'm so embarrassed */ static void poly_sort(int const sort_index, struct Point points[]) { diff --git a/converter/ppm/ppmtoilbm.c b/converter/ppm/ppmtoilbm.c index 5de167dc..69784b37 100644 --- a/converter/ppm/ppmtoilbm.c +++ b/converter/ppm/ppmtoilbm.c @@ -1406,13 +1406,13 @@ void ppm_to_pchg() /* read first slice build a colormap from this slice - select upto <maxcolors> colors + select up to <maxcolors> colors build colormap from selected colors map slice to colormap write slice while( !finished ) { read next slice - compute distances for each pixel and select upto + compute distances for each pixel and select up to <maxchangesperslice> unused colors in this slice modify selected colors to the ones with maximum(?) distance map slice to colormap diff --git a/converter/ppm/ppmtompeg/BUGS b/converter/ppm/ppmtompeg/BUGS index 64269dfb..9724014e 100644 --- a/converter/ppm/ppmtompeg/BUGS +++ b/converter/ppm/ppmtompeg/BUGS @@ -14,7 +14,7 @@ Known BUGS: REFERENCE_FRAME DECODED does not work -5. Cannot use both STDIN and CDL_FILEs (ok, since it doesnt make sense...) +5. Cannot use both STDIN and CDL_FILEs (ok, since it doesn't make sense...) 6. <fixed> diff --git a/converter/ppm/ppmtompeg/CHANGES b/converter/ppm/ppmtompeg/CHANGES index fffa7a65..efb8fdcf 100644 --- a/converter/ppm/ppmtompeg/CHANGES +++ b/converter/ppm/ppmtompeg/CHANGES @@ -28,7 +28,7 @@ Changes chronology - non-integer frame rates now work for all machines - fixed parsing of -mv_histogram - fixed numPadding bug (file name problem) - - fixed full pixel assertation bug + - fixed full pixel assertion bug - corrected ASPECT_RATIO bug (was forced to 1) - buffer size is now set correctly - complains when file is too small diff --git a/converter/ppm/ppmtompeg/bitio.c b/converter/ppm/ppmtompeg/bitio.c index e0dc4d4e..e02fe985 100644 --- a/converter/ppm/ppmtompeg/bitio.c +++ b/converter/ppm/ppmtompeg/bitio.c @@ -245,7 +245,7 @@ Bitio_Write(BitBucket * const bbPtr, /* * Clear top bits if not part of data, necessary due to down and - * dirty calls of Bitio_Write with unecessary top bits set. + * dirty calls of Bitio_Write with unnecessary top bits set. */ bits &= lower_mask[nbits]; diff --git a/converter/ppm/ppmtompeg/bsearch.c b/converter/ppm/ppmtompeg/bsearch.c index 70edfef6..db34d95b 100644 --- a/converter/ppm/ppmtompeg/bsearch.c +++ b/converter/ppm/ppmtompeg/bsearch.c @@ -43,7 +43,7 @@ * Changed copyrights * * Revision 1.6 1994/12/07 00:40:36 smoot - * Added seperate P and B search ranges + * Added separate P and B search ranges * * Revision 1.5 1994/03/15 00:27:11 keving * nothing diff --git a/converter/ppm/ppmtompeg/docs/template.param b/converter/ppm/ppmtompeg/docs/template.param index 66b6dd98..78ad5300 100644 --- a/converter/ppm/ppmtompeg/docs/template.param +++ b/converter/ppm/ppmtompeg/docs/template.param @@ -18,7 +18,7 @@ # files in the order in which they must appear, followed by 'END_INPUT' # # Also, if you use the `command` method of generating input file names, -# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds +# the command will only be executed in the INPUT_DIR if INPUT_DIR precedes # the INPUT parameter. # # <option> MUST be in UPPER CASE diff --git a/converter/ppm/ppmtompeg/examples/template.param b/converter/ppm/ppmtompeg/examples/template.param index 66b6dd98..78ad5300 100644 --- a/converter/ppm/ppmtompeg/examples/template.param +++ b/converter/ppm/ppmtompeg/examples/template.param @@ -18,7 +18,7 @@ # files in the order in which they must appear, followed by 'END_INPUT' # # Also, if you use the `command` method of generating input file names, -# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds +# the command will only be executed in the INPUT_DIR if INPUT_DIR precedes # the INPUT parameter. # # <option> MUST be in UPPER CASE diff --git a/converter/ppm/ppmtompeg/headers/all.h b/converter/ppm/ppmtompeg/headers/all.h index e350aab8..5c559528 100644 --- a/converter/ppm/ppmtompeg/headers/all.h +++ b/converter/ppm/ppmtompeg/headers/all.h @@ -33,7 +33,7 @@ * added little_endian force for irizx * * Revision 1.8 1995/02/02 22:02:18 smoot - * added ifdefs for compatability on stranger and stranger architectures... + * added ifdefs for compatibility on stranger and stranger architectures... * * Revision 1.7 1995/02/02 07:26:45 eyhung * added parens to all.h to remove compiler warning diff --git a/converter/ppm/ppmtompeg/headers/motion_search.h b/converter/ppm/ppmtompeg/headers/motion_search.h index 62f3abab..117b914a 100644 --- a/converter/ppm/ppmtompeg/headers/motion_search.h +++ b/converter/ppm/ppmtompeg/headers/motion_search.h @@ -140,7 +140,7 @@ extern int psearchAlg; * Changed copyrights * * Revision 1.4 1994/12/07 00:42:01 smoot - * Added seperate P and B search ranges + * Added separate P and B search ranges * * Revision 1.3 1994/11/12 02:12:58 keving * nothing diff --git a/converter/ppm/ppmtompeg/headers/rate.h b/converter/ppm/ppmtompeg/headers/rate.h index df5ca1cc..8d691174 100644 --- a/converter/ppm/ppmtompeg/headers/rate.h +++ b/converter/ppm/ppmtompeg/headers/rate.h @@ -64,7 +64,7 @@ targetRateControl(MpegFrame * const frameP); * MB_RateOut * * Prints out sampling of MB rate control data. Every "nth" block - * stats are printed, with "n" controled by global RC_MB_SAMPLE_RATE + * stats are printed, with "n" controlled by global RC_MB_SAMPLE_RATE * * RETURNS: nothing *===========================================================================*/ diff --git a/converter/ppm/ppmtompeg/jpeg.c b/converter/ppm/ppmtompeg/jpeg.c index 2567666d..990317a2 100644 --- a/converter/ppm/ppmtompeg/jpeg.c +++ b/converter/ppm/ppmtompeg/jpeg.c @@ -101,7 +101,7 @@ JMovie2JPEG(const char * const infilename, char ofname[256]; /* output filename string */ int Temp = 0, temp = 0; /* dummy variables */ int image_offset = 0; /* counting variable */ - /* J_Movie header infomation */ + /* J_Movie header information */ int ver_no; /* version number - expected to be 2 */ int fps; /* frame rate - frames per second */ int no_frames; /* total number of frames in jmovie */ @@ -500,7 +500,7 @@ ReadJPEG(MpegFrame * const mf, (void) jpeg_read_raw_data(&cinfo, scanarray, buffer_height); - /* alter subsample ratio's if neccessary */ + /* alter subsample ratio's if necessary */ if ((h_samp[0]==2) && (h_samp[1]==1) && (h_samp[2]==1) && (v_samp[0]==2) && (v_samp[1]==1) && (v_samp[2]==1)) { /* we are 4:1:1 as expected by the encoder*/ diff --git a/converter/ppm/ppmtompeg/opts.c b/converter/ppm/ppmtompeg/opts.c index c4d0c0b3..5b92d829 100644 --- a/converter/ppm/ppmtompeg/opts.c +++ b/converter/ppm/ppmtompeg/opts.c @@ -255,7 +255,7 @@ SetupLocalDCT(const char * const charPtr) * * SetupLaplace * - * Setup encoder to find distrubution for I-frames, and use for -snr + * Setup encoder to find distribution for I-frames, and use for -snr * * RETURNS: nothing * diff --git a/converter/ppm/ppmtompeg/psearch.c b/converter/ppm/ppmtompeg/psearch.c index 83c62d04..3cca1241 100644 --- a/converter/ppm/ppmtompeg/psearch.c +++ b/converter/ppm/ppmtompeg/psearch.c @@ -962,7 +962,7 @@ ShowBFMVHistogram(fpointer) * Changed copyrights * * Revision 1.8 1994/12/07 00:40:36 smoot - * Added seperate P and B search ranges + * Added separate P and B search ranges * * Revision 1.7 1994/11/12 02:09:45 eyhung * full pixel bug diff --git a/converter/ppm/ppmtompeg/rate.c b/converter/ppm/ppmtompeg/rate.c index 0f1bcac1..d92afb64 100644 --- a/converter/ppm/ppmtompeg/rate.c +++ b/converter/ppm/ppmtompeg/rate.c @@ -595,7 +595,7 @@ updateRateControl(int const type) { * MB_RateOut * * Prints out sampling of MB rate control data. Every "nth" block - * stats are printed, with "n" controled by global RC_MB_SAMPLE_RATE + * stats are printed, with "n" controlled by global RC_MB_SAMPLE_RATE * (NB. "skipped" blocks do not go through this function and thus do not * show up in the sample ) * diff --git a/converter/ppm/ppmtompeg/specifics.c b/converter/ppm/ppmtompeg/specifics.c index 38e8fc43..d2093e7f 100644 --- a/converter/ppm/ppmtompeg/specifics.c +++ b/converter/ppm/ppmtompeg/specifics.c @@ -91,7 +91,7 @@ version N Specify the version of the specifics file format (this is 1) frame N T M Sets frame number N to type T and Qscale M - (type T is I,B,P,other, other means unspec. I recomend - ) + (type T is I,B,P,other, other means unspec. I recommend - ) slice M Q Sets slice M (in frame N as defined by a previous frame command) to qscale Q @@ -559,7 +559,7 @@ int start_qs; } else { /* if not next, check from the start. (this allows people to put frames out of order,even - though the spec doesnt allow it.) */ + though the spec doesn't allow it.) */ tmp = fsl; found_it = FALSE; while (tmp != (FrameSpecList *) NULL) { diff --git a/converter/ppm/ppmtoterm.c b/converter/ppm/ppmtoterm.c index 29b35a94..d388f77d 100644 --- a/converter/ppm/ppmtoterm.c +++ b/converter/ppm/ppmtoterm.c @@ -19,6 +19,7 @@ ** */ +#include <assert.h> #include <string.h> #include "pm_c_util.h" @@ -72,9 +73,15 @@ parseCommandLine(int argc, const char ** argv, -#define ESC "\x1B\x5B" -#define NUM_COLORS 128 -#define MAX_ANSI_STR_LEN 16 +#define ESC "\x1B\x5B" +#define ANSI_BRIGHT_CMD_PAT ESC "%dm" +#define ANSI_FGCOLOR_CMD_PAT ESC "3%dm" +#define ANSI_BGCOLOR_CMD_PAT ESC "4%dm" +#define MAX_ANSI_STR_LEN 16 +#define NUM_COLORS 128 + /* 1 bit each RGB = 8 colors. + 8 BG colors * 8 FG colors * 2 brightnesses + */ @@ -85,33 +92,97 @@ generatePalette(unsigned char rgb[NUM_COLORS][3], /*---------------------------------------------------------------------------- Generate some sort of color palette mixing the available colors as different values of background, foreground & brightness. + + We return as rgb[I] the RGB triple for the color with palette index I. + Component intensities are in the range 0..255. rgb[I][0] is red; + rgb[I][1] is green; rgb[I][2] is blue. + + We return as ansiCode[I] the sequence you send to a terminal to generate + the color with palette index I. -----------------------------------------------------------------------------*/ - unsigned int code; - unsigned int col; - unsigned int cd2; - - memset((void *)rgb, 0, NUM_COLORS*3); - memset((void *)ansiCode, 0, NUM_COLORS*MAX_ANSI_STR_LEN); - - for( col = cd2 =0; cd2 < 8; ++cd2) { - unsigned int b; - for (b = 0; b < 2; ++b) { - for (code = 0; code < 8; ++code) { - unsigned int c; - for (c = 0; c < 3; ++c) { - if ((code & (0x1 << c)) != 0) - rgb[col][c] = (192 | (b ? 63 : 0)); - if ((cd2 & (0x1 << c)) != 0) - rgb[col][c] |= 0x80; + unsigned int idx; + /* palette index of the color being considered */ + unsigned int bgColorCode; + /* This is the ANSI color code for the background. An ANSI color code + is a 3 bit code in which LSB means red; middle bit means green, and + MSB means blue. + */ + + /* We develop the palette backwards: consider every permutation of the + three terminal controls -- background, foreground, and brightness -- + and for each figure out what RGB color it represents and fill in + that element of RGB[][] + */ + + for (bgColorCode = 0, idx = 0; bgColorCode < 8; ++bgColorCode) { + unsigned int brightness; /* 0 = dim; 1 = bright */ + for (brightness = 0; brightness < 2; ++brightness) { + unsigned int fgColorCode; + /* ANSI color code for the foreground. See bgColorCode. */ + for (fgColorCode = 0; fgColorCode < 8; ++fgColorCode) { + unsigned int rgbComp; + /* 0 = red; 1 = green; 2 = blue */ + for (rgbComp = 0; rgbComp < 3; ++rgbComp) { + assert (idx < NUM_COLORS); + rgb[idx][rgbComp] = 0x00; /* initial value */ + if ((fgColorCode & (0x1 << rgbComp)) != 0) { + rgb[idx][rgbComp] |= 0xC0; + if (brightness == 1) + rgb[idx][rgbComp] |= 0x3F; + } + if ((bgColorCode & (0x1 << rgbComp)) != 0) + rgb[idx][rgbComp] |= 0x80; } - sprintf(ansiCode[col], - ESC"%dm"ESC"3%dm"ESC"4%dm", - b, code, cd2); - ++col; + sprintf(ansiCode[idx], + ANSI_BRIGHT_CMD_PAT + ANSI_FGCOLOR_CMD_PAT + ANSI_BGCOLOR_CMD_PAT, + brightness, fgColorCode, bgColorCode); + ++idx; } } } - *paletteSizeP = col; + *paletteSizeP = idx; +} + + + +static void +lookupInPalette(pixel const pixel, + pixval const maxval, + unsigned char rgb[NUM_COLORS][3], + unsigned int const palLen, + unsigned int * const paletteIdxP) { +/*---------------------------------------------------------------------------- + Look up the color 'pixel' (which has maxval 'maxval') in the palette + palette[], which has 'palLen' elements and uses maxval 255. Return the + index into palette[] of the color that is closes to 'pixel' as + *paletteIdxP. +-----------------------------------------------------------------------------*/ + pixval const r = PPM_GETR(pixel) * 255 / maxval; + pixval const g = PPM_GETG(pixel) * 255 / maxval; + pixval const b = PPM_GETB(pixel) * 255 / maxval; + + unsigned int paletteIdxSoFar; + unsigned int dist; + unsigned int i; + + /* The following loop calculates the index that corresponds to the + minimum color distance between the given RGB values and the + values available in the palette. + */ + for (i = 0, dist = SQR(255)*3, paletteIdxSoFar = 0; i < palLen; ++i) { + pixval const pr=rgb[i][0]; + pixval const pg=rgb[i][1]; + pixval const pb=rgb[i][2]; + unsigned int const j = SQR(r-pr) + SQR(b-pb) + SQR(g-pg); + + if (j < dist) { + dist = j; + paletteIdxSoFar = i; + } + } + *paletteIdxP = paletteIdxSoFar; } @@ -119,8 +190,8 @@ generatePalette(unsigned char rgb[NUM_COLORS][3], int main(int argc, const char ** argv) { - FILE * ifP; - pixel ** pixels; + FILE * ifP; + pixel ** pixels; int rows, cols; unsigned int row; unsigned int palLen; @@ -144,31 +215,16 @@ main(int argc, const char ** argv) { for (row = 0; row < rows; ++row) { unsigned int col; for (col = 0; col < cols; ++col) { - pixval const r=(int)PPM_GETR(pixels[row][col])*255/maxval; - pixval const g=(int)PPM_GETG(pixels[row][col])*255/maxval; - pixval const b=(int)PPM_GETB(pixels[row][col])*255/maxval; - int val, dist; - unsigned int i; - - /* The following loop calculates the index that corresponds to the - minimum color distance between the given RGB values and the - values available in the palette. - */ - for (i = 0, dist = SQR(255)*3, val = 0; i < palLen; ++i) { - pixval const pr=rgb[i][0]; - pixval const pg=rgb[i][1]; - pixval const pb=rgb[i][2]; - unsigned int const j = SQR(r-pr) + SQR(b-pb) + SQR(g-pg); - if (j < dist) { - dist = j; - val = i; - } - } - printf("%s%c", ansiCode[val], 0xB1); + unsigned int paletteIdx; + + lookupInPalette(pixels[row][col], maxval, rgb, palLen, + &paletteIdx); + + printf("%s\xB1", ansiCode[paletteIdx]); } - printf(ESC"\x30m\n"); + printf(ESC "\x30m\n"); } - printf(ESC"\x30m"); + printf(ESC "\x30m"); ppm_freearray(pixels, rows); diff --git a/converter/ppm/ppmtowinicon.c b/converter/ppm/ppmtowinicon.c index faa6a5ac..836c55d8 100644 --- a/converter/ppm/ppmtowinicon.c +++ b/converter/ppm/ppmtowinicon.c @@ -675,7 +675,7 @@ addEntryToIcon(MS_Ico const MSIconData, * All the icons I found seemed to pad the palette to the max entries * for that bitdepth. * - * The spec indicates this isn't neccessary, but I'll follow this behaviour + * The spec indicates this isn't necessary, but I'll follow this behaviour * just in case. */ if (colors < 3) { diff --git a/converter/ppm/xim.h b/converter/ppm/xim.h index ffe60fb6..27556b30 100644 --- a/converter/ppm/xim.h +++ b/converter/ppm/xim.h @@ -112,7 +112,7 @@ typedef struct XimAsciiHeader { /* Note: * - All data is in char's in order to maintain easily portability * across machines, and some human readibility. -* - Images may be stored as pixmaps (8 bits/pixel) or as seperate +* - Images may be stored as pixmaps (8 bits/pixel) or as separate * red, green, blue channel data (24+ bits/pixel). * - An alpha channel is optional and is found after every num_channels * of data. diff --git a/converter/ppm/ximtoppm.c b/converter/ppm/ximtoppm.c index 92827dd3..ce5e6396 100644 --- a/converter/ppm/ximtoppm.c +++ b/converter/ppm/ximtoppm.c @@ -208,7 +208,7 @@ ReadImageChannel(FILE * const infp, } marker += i; } - /* return to the begining of the next image's bufffer */ + /* return to the beginning of the next image's bufffer */ if (fseek(infp, marker, 0) == -1) { pm_message("ReadImageChannel: can't fseek to location in image buffer" ); return(0); diff --git a/doc/HISTORY b/doc/HISTORY index 96591cb7..8b5ce0f8 100644 --- a/doc/HISTORY +++ b/doc/HISTORY @@ -4,28 +4,17 @@ Netpbm. CHANGE HISTORY -------------- -11.11.12 BJH Release 10.56.05 +11.12.30 BJH Release 10.57.00 - pamscale: fix all black output with resampling. Always broken. - - Build: don't use <alloca.h>. - -11.11.22 BJH Release 10.56.04 + pnmnorm: add -midvalue, -middle . pngtopam: fix crash with invalid tIME chunk. Always broken. -11.11.08 BJH Release 10.56.03 - pamarith: fix wrong result with -multiply. Broken in 10.41. -11.10.13 BJH Release 10.56.02 - - Build: fix compile failure introduced in 10.56.01. - -11.10.10 BJH Release 10.56.01 + pamscale: fix all black output with resampling. Always broken. - pamscale: fix "-pixels must be greater than zero". - Thanks Justin Hart (onyxraven@users.sourceforge.net). + Build: don't use <alloca.h>. 11.09.28 BJH Release 10.56.00 @@ -2476,7 +2465,7 @@ CHANGE HISTORY rgb.txt: move D65 to the end, so "white" is preferred. xwdtopnm: change interpretation of bitmap_pad and bitmap_unit - to accomodate Xfree86 direct color 24 bit xwd. + to accommodate Xfree86 direct color 24 bit xwd. pbmtextps: fix bug where intermediate file gets truncated. @@ -3046,7 +3035,7 @@ CHANGE HISTORY pnmtopng: fix -hist option. - Cygwin build accomodations. Thanks Charles Wilson + Cygwin build accommodations. Thanks Charles Wilson <cwilson@ece.gatech.edu>. Fix ppmtompeg build failure when JPEGLIB = NONE @@ -3525,7 +3514,7 @@ CHANGE HISTORY this. pnm_readpnmrow() changed to do same. external data symbols like this do not work with Mingw. - various changes to accomodate Mingw (native Windows) + various changes to accommodate Mingw (native Windows) and DLLs with Cygwin (Windows). eyuvtoppm: rewrite. Uses Netpbm libraries now. @@ -3897,7 +3886,7 @@ CHANGE HISTORY stamp-date doesn't rely on whoami. - Make file fixes to accomodate more install programs. + Make file fixes to accommodate more install programs. Replace tmpnam() with mkstemp(). @@ -4494,7 +4483,7 @@ Changes since the comp.sources.misc distribution of 31oct88: Moved to the new PNM package: pbmcrop pbmcut pbmenlarge pbminvert. Consolidated into a single pnmflip tool: pbmfliplr pbmfliptb pbmtrnspos. Consolidated into a single pnmcat tool: pbmcatlr pbmcattb. - Added compataliases script for upward compatability with changed tools. + Added compataliases script for upward compatibility with changed tools. Removed xxxtopbm. Added a -headersize flag to macptopbm, to help get around annoying problems in MacPaint file format. diff --git a/doc/INSTALL b/doc/INSTALL index 9412b296..474b61cf 100644 --- a/doc/INSTALL +++ b/doc/INSTALL @@ -133,7 +133,7 @@ Search for your platform name (Solaris, SunOS, NetBSD, Cygwin, BeOS, and Tru64 are among those mentioned) to see recommended settings for your platform. -If your system is even too exotic to accomodate with settings in +If your system is even too exotic to accommodate with settings in config.mk, you may need to modify things in the main make files or pm_config.h.in. diff --git a/editor/pamflip/pamflip.c b/editor/pamflip/pamflip.c index 6cbe4edf..2f711184 100644 --- a/editor/pamflip/pamflip.c +++ b/editor/pamflip/pamflip.c @@ -12,7 +12,7 @@ /* transformNonPbmChunk() is the general transformation function. - It can tranform anything, albeit slowly and expensively. + It can transform anything, albeit slowly and expensively. The following are enhancements for specific cases: diff --git a/editor/pamflip/pamflip_sse.c b/editor/pamflip/pamflip_sse.c index f9a126d5..5a256f9d 100644 --- a/editor/pamflip/pamflip_sse.c +++ b/editor/pamflip/pamflip_sse.c @@ -4,7 +4,7 @@ This is part of the Pamflip program. It contains code that exploits the SSE facility of some CPUs. - This code was orginally written by Akira Urushibata ("Douso") in 2010 and is + This code was originally written by Akira Urushibata ("Douso") in 2010 and is contributed to the public domain by all authors. The author makes the following request (which is not a reservation of legal diff --git a/editor/pamperspective.c b/editor/pamperspective.c index 0291afb4..a75e5243 100644 --- a/editor/pamperspective.c +++ b/editor/pamperspective.c @@ -536,7 +536,7 @@ parseCommandLine(int argc, const char * argv[], parse_enum (bool_text[i], bool_token, bool_option_name[i])); - /* Propagate values where neccessary */ + /* Propagate values where necessary */ if (float_spec[10]) /* --margin */ for (i=11; i<15; i++) /* --top_margin through --right_margin */ diff --git a/editor/pamscale.c b/editor/pamscale.c index 9e613fc5..0a2e955f 100644 --- a/editor/pamscale.c +++ b/editor/pamscale.c @@ -927,7 +927,7 @@ typedef struct { window. The index order is NOT the order of the rows in the image. E.g. line[0] isn't always the topmost row of the window. Rather, the rows are arranged in a cycle and you have to know - indpendently where the topmost one is. E.g. the rows of a 5 + independently where the topmost one is. E.g. the rows of a 5 line window with topmost row at index 3 might be: line[0] = Row 24 @@ -1058,7 +1058,7 @@ createWeightList(unsigned int const targetPos, 10*.022 + 20*.521 + 30*.457 = 24 -----------------------------------------------------------------------------*/ - /* 'windowCenter', is the continous position within the source of + /* 'windowCenter', is the continuous position within the source of the center of the window that will influence target pixel 'targetPos'. 'left' and 'right' are the edges of the window. 'leftPixel' and 'rightPixel' are the pixel positions of the @@ -1652,7 +1652,7 @@ horizontalScale(tuplen * const inputtuplenrow, float const xscale, float * const stretchP) { /*---------------------------------------------------------------------------- - Take the input row 'inputtuplenrow', decribed by *inpamP, and scale + Take the input row 'inputtuplenrow', described by *inpamP, and scale it by a factor of 'xscale', to create the output row 'newtuplenrow', described by *outpamP. diff --git a/editor/pamthreshold.c b/editor/pamthreshold.c index 15ed271a..8369602d 100644 --- a/editor/pamthreshold.c +++ b/editor/pamthreshold.c @@ -302,7 +302,7 @@ analyzeDistribution(struct pam * const inpamP, pm_error("Unable to allocate space for %lu-entry histogram", inpamP->maxval+1); - /* Initialize histogram -- zero occurences of everything */ + /* Initialize histogram -- zero occurrences of everything */ for (i = 0; i <= inpamP->maxval; ++i) histogram[i] = 0; @@ -376,7 +376,7 @@ computeGlobalThreshold(struct pam * const inpamP, Compute the proper threshold to use for the image described by *inpamP, and: - 'histogram' describes the frequency of occurence of the various sample + 'histogram' describes the frequency of occurrence of the various sample values in the image. 'globalRange' describes the range (minimum, maximum) of sample values diff --git a/editor/pbmclean.c b/editor/pbmclean.c index c5f8ffe8..6d813090 100644 --- a/editor/pbmclean.c +++ b/editor/pbmclean.c @@ -276,7 +276,7 @@ cleanrow(const bit * const prevrow, unsigned int * const nFlippedP) { /* ---------------------------------------------------------------------- Work through row, scanning for bits that require flipping, and write - the results to outrow. + the results to 'outrow'. Returns the number of bits flipped within this one row as *nFlippedP. -------------------------------------------------------------------------*/ @@ -328,6 +328,52 @@ cleanrow(const bit * const prevrow, static void +setupInputBuffers(FILE * const ifP, + unsigned int const cols, + int const format, + bit *** const bufferP, + bit ** const edgeRowP, + bit ** const thisRowP, + bit ** const nextRowP) { +/*---------------------------------------------------------------------------- + Initialize input buffers. + We add a margin of 8 bits each on the left and right of the rows. + + On the top and bottom of the image we place an imaginary blank row + ("edgerow") to facilitate the process. +-----------------------------------------------------------------------------*/ + bit ** const buffer = pbm_allocarray_packed(cols+16, 3); + bit * const edgeRow = pbm_allocrow_packed(cols+16); + + bit * nextRow; + unsigned int i; + + for (i = 0; i < pbm_packed_bytes(cols+16); ++i) + edgeRow[i] = 0x00; + + for (i = 0; i < 3; ++i) { + /* Add blank (all white) bytes beside the edges */ + buffer[i][0] = buffer[i][ pbm_packed_bytes( cols +16 ) - 1] = 0x00; + } + nextRow = &buffer[0][1]; + + /* Read the top line into nextrow and clean the right end. */ + + pbm_readpbmrow_packed(ifP, nextRow, cols, format); + + if (cols % 8 > 0){ + nextRow[pbm_packed_bytes(cols) -1 ] >>= (8 - cols % 8); + nextRow[pbm_packed_bytes(cols) -1 ] <<= (8 - cols % 8); + } + *bufferP = buffer; + *edgeRowP = edgeRow; + *thisRowP = &edgeRow[1]; + *nextRowP = nextRow; +} + + + +static void cleanSimple(FILE * const ifP, FILE * const ofP, struct cmdlineInfo const cmdline, @@ -337,49 +383,24 @@ cleanSimple(FILE * const ifP, pixels of a subject pixel to determine whether to erase that pixel. -----------------------------------------------------------------------------*/ bit ** buffer; - bit * prevrow; - bit * thisrow; - bit * nextrow; - bit * outrow; - bit * edgerow; + /* The rows of the input relevant to our current processing: + the current row and the one above and below it. + */ + bit * edgeRow; + /* A blank (all white) row. Constant */ + bit * prevRow; + bit * thisRow; + bit * nextRow; + bit * outRow; int cols, rows, format; unsigned int row; pbm_readpbminit(ifP, &cols, &rows, &format); - /* Initialize input buffers. - We add a margin of 8 bits each on the left and right of the rows. + setupInputBuffers(ifP, cols, format, &buffer, &edgeRow, + &thisRow, &nextRow); - On the top and bottom of the image we place an imaginary blank row - ("edgerow") to facilitate the process. - */ - { - unsigned int i; - - buffer = pbm_allocarray_packed(cols+16, 3); - edgerow = pbm_allocrow_packed(cols+16); - - for (i = 0; i < pbm_packed_bytes(cols+16); ++i) - edgerow[i] = 0x00; - - for (i = 0; i < 3; ++i) { - /* Add blank (all white) bytes beside the edges */ - buffer[i][0] = buffer[i][ pbm_packed_bytes( cols +16 ) - 1] = 0x00; - } - thisrow = &edgerow[1]; - nextrow = &buffer[0][1]; - - /* Read the top line into nextrow and clean the right end. */ - - pbm_readpbmrow_packed(ifP, nextrow, cols, format); - - if (cols % 8 > 0){ - nextrow[pbm_packed_bytes(cols) -1 ] >>= (8 - cols % 8); - nextrow[pbm_packed_bytes(cols) -1 ] <<= (8 - cols % 8); - } - } - - outrow = pbm_allocrow(cols); + outRow = pbm_allocrow(cols); pbm_writepbminit(ofP, cols, rows, 0) ; @@ -388,33 +409,33 @@ cleanSimple(FILE * const ifP, for (row = 0; row < rows; ++row) { unsigned int nFlipped; - prevrow = thisrow; /* Slide up the input row window */ - thisrow = nextrow; + prevRow = thisRow; /* Slide up the input row window */ + thisRow = nextRow; if (row < rows -1){ - nextrow = &buffer[(row+1)%3][1]; + nextRow = &buffer[(row+1)%3][1]; /* We take the address directly instead of shuffling the rows with the help of a temporary. This provision is for proper handling of the initial edgerow. */ - pbm_readpbmrow_packed(ifP, nextrow, cols, format); + pbm_readpbmrow_packed(ifP, nextRow, cols, format); if (cols % 8 > 0){ - nextrow[pbm_packed_bytes(cols) -1 ] >>= (8 - cols % 8); - nextrow[pbm_packed_bytes(cols) -1 ] <<= (8 - cols % 8); + nextRow[pbm_packed_bytes(cols) -1 ] >>= (8 - cols % 8); + nextRow[pbm_packed_bytes(cols) -1 ] <<= (8 - cols % 8); } } else /* Bottom of image. */ - nextrow = & edgerow[1]; + nextRow = &edgeRow[1]; - cleanrow(prevrow, thisrow, nextrow, outrow, cols, cmdline.minneighbors, + cleanrow(prevRow, thisRow, nextRow, outRow, cols, cmdline.minneighbors, cmdline.flipWhite, cmdline.flipBlack, &nFlipped); *nFlippedP += nFlipped; - pbm_writepbmrow_packed(ofP, outrow, cols, 0) ; + pbm_writepbmrow_packed(ofP, outRow, cols, 0) ; } pbm_freearray(buffer, 3); - pbm_freerow(edgerow); - pbm_freerow(outrow); + pbm_freerow(edgeRow); + pbm_freerow(outRow); } @@ -491,7 +512,9 @@ pixQueue_push(PixQueue * const queueP, static pm_pixelcoord pixQueue_pop(PixQueue * const queueP) { - +/*---------------------------------------------------------------------------- + Pop and return the pixel location at the head of queue *queueP. +-----------------------------------------------------------------------------*/ struct PixQueueElt * const newHeadP = queueP->headP->nextP; pm_pixelcoord retval; @@ -581,7 +604,10 @@ static void setColor(PixQueue * const blobP, bit ** const pixels, bit const newColor) { - +/*---------------------------------------------------------------------------- + Change all the pixels in (blobP) to 'newColor'. More precisely, change + the pixels in 'pixels' that are listed in *blobP. +-----------------------------------------------------------------------------*/ while (!pixQueue_isEmpty(blobP)) { pm_pixelcoord const thisPix = pixQueue_pop(blobP); @@ -602,7 +628,8 @@ processBlob(pm_pixelcoord const start, /*---------------------------------------------------------------------------- Process the blob that contains the pixel at 'start'. - That pixel is part of a blob. + That pixel is part of a blob. A blob is a maximal set of contiguous + pixels of the same color. None of the blob is marked visited in visited[][]. diff --git a/editor/pnmnorm.c b/editor/pnmnorm.c index 55466630..56685ee0 100644 --- a/editor/pnmnorm.c +++ b/editor/pnmnorm.c @@ -31,7 +31,9 @@ #include "pm_c_util.h" #include "mallocvar.h" +#include "nstring.h" #include "shhopt.h" +#include "matrix.h" #include "pnm.h" enum brightMethod {BRIGHT_LUMINOSITY, BRIGHT_COLORVALUE, BRIGHT_SATURATION}; @@ -40,7 +42,7 @@ struct cmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ - const char *inputFilespec; /* Filespec of input file */ + const char * inputFileName; /* Name of input file */ unsigned int bvalueSpec; xelval bvalue; unsigned int bpercentSpec; @@ -49,6 +51,9 @@ struct cmdlineInfo { xelval wvalue; unsigned int wpercentSpec; float wpercent; + float middle; + unsigned int midvalueSpec; + xelval midvalue; enum brightMethod brightMethod; unsigned int keephues; float maxExpansion; @@ -56,6 +61,7 @@ struct cmdlineInfo { by per centile. This is a factor, not a per cent increase. E.g. 50% increase means a factor of 1.50. */ + unsigned int verbose; }; @@ -79,7 +85,7 @@ parseCommandLine(int argc, const char ** argv, optStruct3 opt; unsigned int luminosity, colorvalue, saturation; - unsigned int maxexpandSpec; + unsigned int middleSpec, maxexpandSpec; float maxexpand; unsigned int option_def_index; @@ -95,6 +101,10 @@ parseCommandLine(int argc, const char ** argv, &cmdlineP->bvalue, &cmdlineP->bvalueSpec, 0); OPTENT3(0, "wvalue", OPT_UINT, &cmdlineP->wvalue, &cmdlineP->wvalueSpec, 0); + OPTENT3(0, "middle", OPT_FLOAT, + &cmdlineP->middle, &middleSpec, 0); + OPTENT3(0, "midvalue", OPT_UINT, + &cmdlineP->midvalue, &cmdlineP->midvalueSpec, 0); OPTENT3(0, "maxexpand", OPT_FLOAT, &maxexpand, &maxexpandSpec, 0); OPTENT3(0, "keephues", OPT_FLAG, @@ -107,6 +117,8 @@ parseCommandLine(int argc, const char ** argv, NULL, &saturation, 0); OPTENT3(0, "brightmax", OPT_FLAG, NULL, &colorvalue, 0); + OPTENT3(0, "verbose", OPT_FLAG, + NULL, &cmdlineP->verbose, 0); /* Note: -brightmax was documented and accepted long before it was actually implemented. By the time we implemented it, we @@ -138,6 +150,14 @@ parseCommandLine(int argc, const char ** argv, pm_error("You specified a per centage > 100 for bpercent: %f", cmdlineP->bpercent); + if (middleSpec) { + if (cmdlineP->middle < 0.0 || cmdlineP->middle > 1.0) + pm_error("-middle is a normalized brightness value; it " + "must be in the range 0..1. You specified %f", + cmdlineP->middle); + } else + cmdlineP->middle = 0.5; + if (luminosity + colorvalue + saturation > 1) pm_error("You can specify only one of " "-luminosity, -colorvalue, and -saturation"); @@ -163,9 +183,9 @@ parseCommandLine(int argc, const char ** argv, "specification. " "You specified %d arguments.", argc-1); if (argc-1 < 1) - cmdlineP->inputFilespec = "-"; + cmdlineP->inputFileName = "-"; else - cmdlineP->inputFilespec = argv[1]; + cmdlineP->inputFileName = argv[1]; } @@ -482,14 +502,25 @@ computeEndValues(FILE * const ifP, int const format, struct cmdlineInfo const cmdline, xelval * const bvalueP, - xelval * const wvalueP) { + xelval * const wvalueP, + bool * const quadraticP, + xelval * const midvalueP) { /*---------------------------------------------------------------------------- - Figure out what original values will be translated to full white and - full black -- thus defining to what all the other values get translated. - - This may involve looking at the image. The image is in the file - 'ifp', which is positioned just past the header (at the raster). - Leave it positioned arbitrarily. + Figure out what original values will be translated to full bright and full + dark and, if user requested, a middle brightness -- thus defining to what + all the other values get translated. + + This may involve looking at the image. The image is in the file 'ifP', + which is positioned just past the header (at the raster). Leave it + positioned arbitrarily. + + We return *quadraticP == true iff the normalization is to be via a + quadratic transfer function fixed at 3 points - full bright, full dark, and + something in between. In that case, the original brightnesses of those + three points are *bvalueP, *midvalueP, and *wvalueP. We return *quadraticP + == false iff the normalization is to be via a linear function fixed at 2 + points - full bright and full dark. In that case, *midvalueP is + meaningless. -----------------------------------------------------------------------------*/ xelval reqBvalue, reqWvalue, nonOlapBvalue, nonOlapWvalue; unsigned int bLower, wRaise; @@ -507,15 +538,187 @@ computeEndValues(FILE * const ifP, *bvalueP = nonOlapBvalue - bLower; *wvalueP = nonOlapWvalue + wRaise; + + if (cmdline.midvalueSpec) { + if (cmdline.midvalue > *bvalueP && cmdline.midvalue < *wvalueP) { + *quadraticP = true; + *midvalueP = cmdline.midvalue; + } else + *quadraticP = false; + } else + *quadraticP = false; +} + + + +static void +computeLinearTransfer(xelval const bvalue, + xelval const wvalue, + xelval const maxval, + xelval * const newBrightness) { +/*---------------------------------------------------------------------------- + Map the middle brightnesses (the ones that don't get clipped to full dark + or full bright, i.e. from 'bvalue' to 'wvalue') linearly onto 0..maxval. + Set this mapping in newBrightness[]. +-----------------------------------------------------------------------------*/ + unsigned int const range = wvalue - bvalue; + + xelval i; + unsigned int val; + /* The following for structure is a hand optimization of this one: + for (i = bvalue; i <= wvalue; ++i) + newBrightness[i] = (i-bvalue)*maxval/range); + (with proper rounding) + */ + for (i = bvalue, val = range/2; + i <= wvalue; + ++i, val += maxval) + newBrightness[i] = MIN(val / range, maxval); + + assert(newBrightness[bvalue] == 0); + assert(newBrightness[wvalue] == maxval); +} + + + +typedef struct { +/*---------------------------------------------------------------------------- + A quadratic polynomial function +-----------------------------------------------------------------------------*/ + double a; /* x^2 coefficient */ + double b; /* x^1 coefficient */ + double c; /* x^0 coefficient */ +} Quadfn; + + + +static void +computeQuadraticFunction(xelval const bvalue, + xelval const midvalue, + xelval const wvalue, + xelval const middle, + xelval const maxval, + Quadfn * const functionP) { + + /* The matrix equation we solve (for varMatrix) is + + a * x = c + */ + double ** a; + double c[3]; + double x[3]; + const char * error; + + MALLOCARRAY2_NOFAIL(a, 3, 3); + + a[0][0] = SQR(bvalue); a[0][1] = bvalue; a[0][2] = 1.0; + a[1][0] = SQR(midvalue); a[1][1] = midvalue; a[1][2] = 1.0; + a[2][0] = SQR(wvalue); a[2][1] = wvalue; a[2][2] = 1.0; + + c[0] = 0.0; + c[1] = middle; + c[2] = maxval; + + pm_solvelineareq(a, x, c, 3, &error); + + if (error) { + pm_error("Cannot fit a quadratic function to the points " + "(%u, %u), (%u, %u), and (%u, %u). %s", + bvalue, 0, midvalue, middle, wvalue, maxval, error); + pm_strfree(error); + } else { + functionP->a = x[0]; + functionP->b = x[1]; + functionP->c = x[2]; + } + + pm_freearray2((void **)a); +} + + + +static void +computeQuadraticTransfer(xelval const bvalue, + xelval const midvalue, + xelval const wvalue, + float const middleNorm, + xelval const maxval, + bool const verbose, + xelval * const newBrightness) { +/*---------------------------------------------------------------------------- + Map the middle brightnesses (the ones that don't get clipped to full dark + or full bright, i.e. from 'bvalue' to 'wvalue') quadratically onto + 0..maxval, such that 'bvalue' maps to 0, 'wvalue' maps to 'maxval, and + 'midvalue' maps to the normalized value 'middleNorm' (i.e. the actual + xelval middleNorm * maxval). + + Set this mapping in newBrightness[]. +-----------------------------------------------------------------------------*/ + xelval const middle = ROUNDU(middleNorm * maxval); + + /* Computing this function is just the task of finding a parabola that + passes through 3 given points: + + (bvalue, 0) + (midvalue, middle) + (wvalue, maxval) + + We do that by solving the system of three linear equations in + in 3 variables. The 3 variables are the coefficients of the + quadratic function we're looking for -- A, B, and C in this: + + NEWVAL = A * OLDVAL^2 + B * OLDVAL + C + + The three equations of the system are: + + 0 = A * bvalue^2 + B * bvalue + C + middle = A * midvalue^2 + B * midvalue + C + maxval = A * wvalue^2 + B * wvalue + C + + Expressed in matrix form: + + [ bvalue^2 bvalue 1 ] [ A ] [ 0 ] + [ midvalue^2 midvalue 1 ] * [ B ] = [ middle ] + [ wvalue^2 wvalue 1 ] [ C ] [ maxval ] + + So we solve that for A, B, and C. + + With those coefficients, we have the quadratic function, and we + simple apply it to every old sample value I in the range to get the + new: + + newBrightness[I] = A * I^2 + B * I + C + */ + + Quadfn xfer; + + computeQuadraticFunction(bvalue, midvalue, wvalue, middle, maxval, + &xfer); + + + if (verbose) + pm_message("Transfer function is %f * s^2 + %f * s + %f", + xfer.a, xfer.b, xfer.c); + + { + xelval i; + for (i = bvalue; i <= wvalue; ++i) + newBrightness[i] = + MIN(ROUNDU(xfer.a * SQR(i) + xfer.b * i + xfer.c), maxval); + } } static void -computeTransferFunction(xelval const bvalue, - xelval const wvalue, - xelval const maxval, - xelval ** const newBrightnessP) { +computeTransferFunction(bool const quadratic, + xelval const bvalue, + xelval const midvalue, + xelval const wvalue, + float const middle, + xelval const maxval, + bool const verbose, + xelval ** const newBrightnessP) { /*---------------------------------------------------------------------------- Compute the transfer function, i.e. the array *newBrightnessP such that (*newBrightnessP)[x] is the brightness of the xel that should replace a @@ -524,9 +727,16 @@ computeTransferFunction(xelval const bvalue, 'bvalue' is the highest brightness that should map to zero brightness; 'wvalue' is the lowest brightness that should map to full brightness. - brightnesses in between should be stretched linearly. (That stretching - could conceivably result in more brightnesses mapping to zero and full - brightness, due to rounding). + + If 'quadratic' is false, brightnesses in between should be stretched + linearly. Otherwise, brightness 'midvalue' should map to brightness + 'middle' (which is expressed on a 0..1 normalized scale) and brightnesses + should be stretched according to a quadratic polynomial that includes those + 3 points. + + This stretching could conceivably result in more brightnesses mapping to + zero and full brightness that 'bvalue' and 'wvalue' demand, due to + rounding. Define function only for values 0..maxval. -----------------------------------------------------------------------------*/ @@ -543,23 +753,13 @@ computeTransferFunction(xelval const bvalue, for (i = 0; i < bvalue; ++i) newBrightness[i] = 0; - /* Map the middle brightnesses linearly onto 0..maxval */ - { - unsigned int const range = wvalue - bvalue; - unsigned int val; - /* The following for loop is a hand optimization of this one: - for (i = bvalue; i <= wvalue; ++i) - newBrightness[i] = (i-bvalue)*maxval/range); - (with proper rounding) - */ - for (i = bvalue, val = range/2; - i <= wvalue; - ++i, val += maxval) - newBrightness[i] = MIN(val / range, maxval); - - assert(newBrightness[bvalue] == 0); - assert(newBrightness[wvalue] == maxval); - } + /* Map the middle brightnesses onto 0..maxval */ + + if (quadratic) + computeQuadraticTransfer(bvalue, midvalue, wvalue, middle, maxval, + verbose, newBrightness); + else + computeLinearTransfer(bvalue, wvalue, maxval, newBrightness); /* Clip the highest brightnesses to maxval */ for (i = wvalue+1; i <= maxval; ++i) @@ -653,6 +853,25 @@ writeRowNormalized(xel * const xelrow, +static void +reportTransferParm(bool const quadratic, + xelval const bvalue, + xelval const midvalue, + xelval const wvalue, + xelval const maxval, + float const middle) { + + if (quadratic) + pm_message("remapping %u..%u..%u to %u..%u..%u", + bvalue, midvalue, wvalue, + 0, ROUNDU(maxval*middle), maxval); + else + pm_message("remapping %u..%u to %u..%u", + bvalue, wvalue, 0, maxval); +} + + + int main(int argc, const char *argv[]) { @@ -661,20 +880,21 @@ main(int argc, const char *argv[]) { pm_filepos imagePos; xelval maxval; int rows, cols, format; - xelval bvalue, wvalue; + bool quadratic; + xelval bvalue, midvalue, wvalue; pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); - ifP = pm_openr_seekable(cmdline.inputFilespec); + ifP = pm_openr_seekable(cmdline.inputFileName); /* Rescale so that bvalue maps to 0, wvalue maps to maxval. */ pnm_readpnminit(ifP, &cols, &rows, &maxval, &format); pm_tell2(ifP, &imagePos, sizeof(imagePos)); computeEndValues(ifP, cols, rows, maxval, format, cmdline, - &bvalue, &wvalue); + &bvalue, &wvalue, &quadratic, &midvalue); { xelval * newBrightness; int row; @@ -685,9 +905,13 @@ main(int argc, const char *argv[]) { xelrow = pnm_allocrow(cols); - pm_message("remapping %u..%u to %u..%u", bvalue, wvalue, 0, maxval); + reportTransferParm(quadratic, bvalue, midvalue, wvalue, maxval, + cmdline.middle); - computeTransferFunction(bvalue, wvalue, maxval, &newBrightness); + + computeTransferFunction(quadratic, bvalue, midvalue, wvalue, + cmdline.middle, maxval, cmdline.verbose, + &newBrightness); pm_seek2(ifP, &imagePos, sizeof(imagePos)); pnm_writepnminit(stdout, cols, rows, maxval, format, 0); @@ -704,6 +928,9 @@ main(int argc, const char *argv[]) { pnm_freerow(rowbuf); pnm_freerow(xelrow); } - pm_close(ifP); + pm_close(ifP); return 0; } + + + diff --git a/editor/pnmpad.c b/editor/pnmpad.c index bbb85e8b..1904b687 100644 --- a/editor/pnmpad.c +++ b/editor/pnmpad.c @@ -163,7 +163,7 @@ static void parseCommandLineOld(int argc, const char ** argv, struct cmdlineInfo * const cmdlineP) { - /* This syntax was abandonned in February 2002. */ + /* This syntax was abandoned in February 2002. */ pm_message("Warning: old style options are deprecated!"); cmdlineP->xsize = cmdlineP->ysize = 0; diff --git a/editor/pnmstitch.c b/editor/pnmstitch.c index e7887232..849445fb 100644 --- a/editor/pnmstitch.c +++ b/editor/pnmstitch.c @@ -77,7 +77,7 @@ * - Add RotateCrop filter algorithm (in-memory copy of image, * detect least loss horizontal crop on a rotated image). * - pnmstitch should be generalized to handle transformation - * occuring on the left image, currently it blends assuming + * occurring on the left image, currently it blends assuming * that there is no transformation effects on the left image. * - user selectable blending algorithms? */ @@ -893,7 +893,7 @@ stitchOneRow(Image * const Left, * We scale the overlap of the left and right images, we need to * discover and hold on to the left edge of the right image to * determine the rate at which we blend. Most (7/8) of the blending - * occurs in the first half of the overlap to reduce the occurences + * occurs in the first half of the overlap to reduce the occurrences * of blending artifacts. If there is no overlap, the image present * has no blending activity, this is determined by the black * background and is not through an alpha layer to help reduce @@ -1393,7 +1393,7 @@ LinearConstrain(Stitcher * me, int x, int y, int width, int height) * width sliver of the left hand side of the right image and compare * the sample to the left hand image. Accuracy is honored over speed. * The image overlap is expected between 7/16 to 1/16 in the horizontal - * position, and a minumum of 5/8 in the vertical dimension. + * position, and a minimum of 5/8 in the vertical dimension. * * Blind alleys: * - reduced resolution can match in totally wrong regions, @@ -2071,7 +2071,7 @@ BiLinearConstrain(Stitcher * me, int x, int y, int width, int height) * width sliver of the left hand side of the right image and compare * the sample to the left hand image. Accuracy is honored over speed. * The image overlap is expected between 7/16 to 1/16 in the horizontal - * position, and a minumum of 5/8 in the vertical dimension. + * position, and a minimum of 5/8 in the vertical dimension. * * Blind alleys: * - Tried a simpler constraint for right side to be `back' diff --git a/lib/Makefile b/lib/Makefile index f39dbadc..8d9b3175 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -42,6 +42,7 @@ LIBOBJECTS_X = \ util/filename.o \ util/io.o \ util/mallocvar.o \ + util/matrix.o \ util/nsleep.o \ util/nstring.o \ util/shhopt.o \ diff --git a/lib/libpammap.c b/lib/libpammap.c index f73ec45e..8477875a 100644 --- a/lib/libpammap.c +++ b/lib/libpammap.c @@ -189,7 +189,7 @@ addColorOccurrenceToHash(tuple const color, p = p->next); if (p) { - /* It's in the hash; just tally one more occurence */ + /* It's in the hash; just tally one more occurrence */ ++p->tupleint.value; *fullP = FALSE; } else { @@ -227,7 +227,7 @@ pnm_addtuplefreqoccurrence(struct pam * const pamP, p = p->next); if (p) { - /* It's in the hash; just tally one more occurence */ + /* It's in the hash; just tally one more occurrence */ ++p->tupleint.value; *firstOccurrenceP = FALSE; } else { diff --git a/lib/util/Makefile b/lib/util/Makefile index 0cb23449..5bf1995e 100644 --- a/lib/util/Makefile +++ b/lib/util/Makefile @@ -13,6 +13,7 @@ UTILOBJECTS = \ filename.o \ io.o \ mallocvar.o \ + matrix.o \ nsleep.o \ nstring.o \ shhopt.o \ diff --git a/lib/util/floatcode.h b/lib/util/floatcode.h index 6079c142..dc31d038 100644 --- a/lib/util/floatcode.h +++ b/lib/util/floatcode.h @@ -163,7 +163,7 @@ pm_bigendDoubleFromDouble(double const arg) { } break; case LITTLE_ENDIAN: { union { - unsigned char bytes[4]; + unsigned char bytes[8]; double native; } converter; diff --git a/lib/util/matrix.c b/lib/util/matrix.c new file mode 100644 index 00000000..5101f2c3 --- /dev/null +++ b/lib/util/matrix.c @@ -0,0 +1,219 @@ +/*============================================================================= + matrix +=============================================================================== + + Matrix math. + +=============================================================================*/ + +#include <assert.h> +#include <math.h> +#include <stdlib.h> +#include <stdio.h> + +#include "pm_c_util.h" +#include "mallocvar.h" +#include "nstring.h" + +#include "matrix.h" + + +static double const epsilon = 1e-10; + + + +static void +swap(double * const aP, + double * const bP) { + + double const oldA = *aP; + + *aP = *bP; + *bP = oldA; +} + + + +static void +initializeWorkMatrices(unsigned int const n, + double ** const aInit, + const double * const cInit, + double *** const aP, + double ** const cP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Allocate memory for an n x n matrix, initialize it to the value of + aInit[], and return it as *aP. + + Allocate memory for an n x 1 matrix, initialize it to the value of + cInit[], and return it as *cP. +-----------------------------------------------------------------------------*/ + double ** a; + double * c; + + MALLOCARRAY2(a, n, n); + if (a == NULL) + pm_asprintf(errorP, "Could not get memory for a %u x %u matrix", n, n); + else { + unsigned int i; + for (i = 0; i < n; ++i) { + unsigned int j; + for (j = 0; j < n; ++j) + a[i][j] = aInit[i][j]; + } + MALLOCARRAY(c, n); + if (c == NULL) + pm_asprintf(errorP, "Could not get memory for a %u x 1 matrix", n); + else { + unsigned int i; + for (i = 0; i < n; ++i) + c[i] = cInit[i]; + + *errorP = NULL; + } + if (*errorP) + free(a); + } + *aP = a; + *cP = c; +} + + + +static void +findLargestIthCoeff(unsigned int const n, + double ** const a, + unsigned int const i, + unsigned int * const istarP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Among the 'i'th and following rows in 'a' (which has 'n' total rows), + find the one with the largest 'i'th column. + + And it had better be greater than zero; if not, we fail (return *errorP + non-null). + + Return its index as *istarP. +-----------------------------------------------------------------------------*/ + double maxSoFar; + unsigned int maxIdx; + unsigned int ii; + + for (ii = i, maxSoFar = 0.0; ii < n; ++ii) { + double const thisA = fabs(a[ii][i]); + if (thisA >= maxSoFar) { + maxIdx = ii; + maxSoFar = thisA; + } + } + if (maxSoFar < epsilon) + pm_asprintf(errorP, "Matrix equation has no unique solution. " + "(debug: coeff %u %e < %e)", i, maxSoFar, epsilon); + else { + *istarP = maxIdx; + *errorP = NULL; + } +} + + + +static void +eliminateOneUnknown(unsigned int const i, + unsigned int const n, + double ** const a, + double * const c, + const char ** const errorP) { + + unsigned int maxRow; + + findLargestIthCoeff(n, a, i, &maxRow, errorP); + + if (!*errorP) { + /* swap rows 'i' and 'maxRow' in 'a' and 'c', so that the ith + row has the largest ith coefficient. + */ + unsigned int j; + for (j = 0; j < n; j++) + swap(&a[maxRow][j], &a[i][j]); + + swap(&c[maxRow], &c[i]); + + /* Combine rows so that the ith coefficient in every row below + the ith is zero. + */ + { + unsigned int ii; + for (ii = i+1; ii < n; ++ii) { + double const multiplier = a[ii][i] / a[i][i]; + /* This is what we multiply the whole ith row by to make + its ith coefficient equal to that in the iith row. + */ + unsigned int j; + + /* Combine ith row into iith row so that the ith coefficient + in the iith is zero. + */ + c[ii] = c[ii] - multiplier * c[i]; + + for (j = 0; j < n; ++j) + a[ii][j] = a[ii][j] - multiplier * a[i][j]; + + assert(a[ii][i] < epsilon); + } + } + *errorP = NULL; + } +} + + + +void +pm_solvelineareq(double ** const aArg, + double * const x, + double * const cArg, + unsigned int const n, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Solve the matrix equation 'a' * 'x' = 'c' for 'x'. + + 'n' is the dimension of the matrices. 'a' is 'n' x 'n', + while 'x' and 'c' are 'n' x 1. +-----------------------------------------------------------------------------*/ + /* We use Gaussian reduction. */ + + double ** a; + double * c; + + initializeWorkMatrices(n, aArg, cArg, &a, &c, errorP); + + if (!*errorP) { + unsigned int i; + + for (i = 0, *errorP = NULL; i < n && !*errorP; ++i) + eliminateOneUnknown(i, n, a, c, errorP); + + if (!*errorP) { + /* a[] now has all zeros in the lower left triangle. */ + /* Work from the bottom up to solve for the unknowns x[], from + the a and c rows in question and all the x[] below it + */ + + unsigned int k; + for (k = 0; k < n; ++k) { + unsigned int const m = n - k - 1; + unsigned int j; + double xwork; + + for (j = m+1, xwork = c[m]; j < n; ++j) + xwork -= a[m][j] * x[j]; + + x[m] = xwork / a[m][m]; + } + } + } + pm_freearray2((void**)a); + free(c); +} + + + diff --git a/lib/util/matrix.h b/lib/util/matrix.h new file mode 100644 index 00000000..13ae0373 --- /dev/null +++ b/lib/util/matrix.h @@ -0,0 +1,11 @@ +#ifndef MATRIX_H_INCLUDED +#define MATRIX_H_INCLUDED + +void +pm_solvelineareq(double ** const aArg, + double * const x, + double * const cArg, + unsigned int const n, + const char ** const errorP); + +#endif diff --git a/lib/util/nstring.c b/lib/util/nstring.c index 03439cad..e3aa5565 100644 --- a/lib/util/nstring.c +++ b/lib/util/nstring.c @@ -113,6 +113,10 @@ */ +#define _GNU_SOURCE + /* Due to conditional compilation, this is GNU source only if the C library + is GNU. + */ #define PORTABLE_SNPRINTF_VERSION_MAJOR 2 #define PORTABLE_SNPRINTF_VERSION_MINOR 2 @@ -130,6 +134,12 @@ #include "nstring.h" +#if (defined(__GLIBC__) || defined(__GNU_LIBRARY__)) + #define HAVE_VASPRINTF 1 +#else + #define HAVE_VASPRINTF 0 +#endif + #ifdef isdigit #undef isdigit #endif @@ -745,26 +755,30 @@ pm_asprintf(const char ** const resultP, const char * const fmt, ...) { + const char * result; va_list varargs; +#if HAVE_VASPRINTF + va_start(varargs, fmt); + vasprintf((char **)&result, fmt, varargs); + va_end(varargs); +#else size_t dryRunLen; va_start(varargs, fmt); - + pm_vsnprintf(NULL, 0, fmt, varargs, &dryRunLen); va_end(varargs); if (dryRunLen + 1 < dryRunLen) /* arithmetic overflow */ - *resultP = pm_strsol; + result = NULL; else { size_t const allocSize = dryRunLen + 1; char * result; result = malloc(allocSize); - if (result == NULL) - *resultP = pm_strsol; - else { + if (result != NULL) { va_list varargs; size_t realLen; @@ -774,10 +788,14 @@ pm_asprintf(const char ** const resultP, assert(realLen == dryRunLen); va_end(varargs); - - *resultP = result; } } +#endif + + if (result == NULL) + *resultP = pm_strsol; + else + *resultP = result; } diff --git a/lib/util/shhopt.c b/lib/util/shhopt.c index 2e7c6abd..4f7ce9c7 100644 --- a/lib/util/shhopt.c +++ b/lib/util/shhopt.c @@ -849,7 +849,7 @@ parse_long_option(char * const argv[], | | This differs from pm_optParseOptions in that it accepts | long options with just one hyphen and doesn't accept - | any short options. It also has accomodations for + | any short options. It also has accommodations for | future expansion. | | Options and arguments used are removed from the argv- @@ -934,7 +934,7 @@ zero_specified(optEntry opt_table[]) { | | This differs from pm_optParseOptions in that it accepts | long options with just one hyphen and doesn't accept - | any short options. It also has accomodations for + | any short options. It also has accommodations for | future expansion. | | Options and arguments used are removed from the argv- diff --git a/urt/rle_open_f.c b/urt/rle_open_f.c index 0f1fc757..956d5d01 100644 --- a/urt/rle_open_f.c +++ b/urt/rle_open_f.c @@ -234,7 +234,7 @@ dealWithSubprocess(const char * const file_name, * will return a pointer to stdin or stdout depending on the mode. * If the user specifies a non-null file name and an I/O error occurs * when trying to open the file, rle_open_f will terminate execution with - * an appropiate error message. + * an appropriate error message. * * parameters * input: diff --git a/urt/rle_putrow.c b/urt/rle_putrow.c index 230720f8..e85d83d8 100644 --- a/urt/rle_putrow.c +++ b/urt/rle_putrow.c @@ -62,7 +62,7 @@ * Assumptions: * * Algorithm: - * Search for occurences of pixels not of the given color outside + * Search for occurrences of pixels not of the given color outside * the runs already found. When some are found, add a new run or * extend an existing one. Adjacent runs with fewer than two * pixels intervening are merged. diff --git a/version.mk b/version.mk index c48a3a20..4e2b8c7e 100644 --- a/version.mk +++ b/version.mk @@ -1,4 +1,4 @@ NETPBM_MAJOR_RELEASE = 10 -NETPBM_MINOR_RELEASE = 56 -NETPBM_POINT_RELEASE = 5 +NETPBM_MINOR_RELEASE = 57 +NETPBM_POINT_RELEASE = 0 |