📄 pnmtoljpg.c
字号:
/* * pnmtoljpg.c -- * * This is the main routine for the lossless JPEG encoder. * * Copyright (c) 1994 Kongji Huang and Brian C. Smith. * Cornell University * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice and the following * two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <string.h>#include "jpeg.h"#include "mcu.h"#include "proto.h"#include "pnmtoljpg.h"/* * Global and static variables */int verbose; /* If verbose!=0, the verbose flag is on. */int psvSet[7]; /* The PSV set */int numSelValue; /* Number of elements in psvPSV */long inputFileBytes; /* Total input file bytes */long outputFileBytes; /* Total output file bytes */long totalHuffSym[7]; /* Total bits of Huffman coded categroy symbols */long totalAddBits[7]; /* Total additional bits */static FILE *outFile; /* Output file pointer *//* *-------------------------------------------------------------- * * WriteJpegData -- * * This is an interface routine to the JPEG library. The * library calls this routine to output a block of data. * * Results: * Number of bytes written. If this is less than numBytes, * it indeicates an error. * * Side effects: * The number of bytes output this time is added to * outputFileBytes. * *-------------------------------------------------------------- */intWriteJpegData (buffer, numBytes) char *buffer; /* Data to write */ int numBytes; /* Number of bytes to write */{ outputFileBytes+=numBytes; return fwrite(buffer, 1, numBytes, outFile);}/* *-------------------------------------------------------------- * * ArgParser -- * * Command line parser. * * Results: * Command line parameters and options are passed out. * * Side effects: * Exit on error. * *-------------------------------------------------------------- */static void ArgParser(enInfo,argc,argv,optimize,verbose,inFile,outFile) CompressInfo *enInfo; int argc; char **argv; int *optimize; int *verbose; FILE **inFile, **outFile;{ int argn; char *arg; char *usage="pnmtoljpg [-d -h -v -p# -r# -s{0..7}] [InFile [outFile]]"; int numOfFiles=0; int i,psv; /* * default values */ enInfo->restartInRows=0; enInfo->Pt=0; *optimize=1; *inFile=stdin; *outFile=stdout; *verbose=0; numSelValue=7; for (i=0;i<numSelValue;i++) { psvSet[i]=i+1; } for (argn = 1; argn < argc; argn++) { arg=argv[argn]; if (*arg != '-') { /* * process a file name */ if (numOfFiles==0) { if ((*inFile=fopen(arg,"r"))==NULL) { fprintf(stderr,"Can't open %s\n",arg); exit(-1); } } if (numOfFiles==1) { if ((*outFile=fopen(arg,"w"))==NULL) { fprintf(stderr,"Can't open %s\n",arg); exit(-1); } } if (numOfFiles>1) { fprintf(stderr,"%s\n",usage); exit(-1); } numOfFiles++; } else { /* * precess a option */ arg++; switch (*arg) { case 'd': /* * default Huffman table flag */ *optimize=0; break; case 'h': /* * help flag */ fprintf(stderr,"Encode a PPM or PGM image into "); fprintf(stderr,"a lossless JPEG image.\n"); fprintf(stderr,"Usage:\n"); fprintf(stderr,"%s\n",usage); fprintf(stderr,"default input\tstdin\n"); fprintf(stderr,"default output\tstdout\n"); fprintf(stderr,"-d\t\tuse default Huffman table\n"); fprintf(stderr,"-h\t\thelp\n"); fprintf(stderr,"-p#\t\t# is the point tranform "); fprintf(stderr,"parameter, a positive integer\n"); fprintf(stderr,"\t\tless than "); fprintf(stderr,"sample precision.\n"); fprintf(stderr,"-r#\t\trestart at every # rows\n"); fprintf(stderr,"-s{1..7}\t{1..7} is a set of predictor"); fprintf(stderr," selection values, e.g. -s146.\n"); fprintf(stderr,"-v\t\tverbose\n"); exit(1); break; case 'p': /* * point transform parameter */ enInfo->Pt=*(++arg)-'0'; break; case 's': /* * predictor selection value set */ psv=*(++arg)-'0'; numSelValue=0; while ((psv>0) && (psv<8)) { psvSet[numSelValue++]=psv; psv=*(++arg)-'0'; } break; case 'r': /* * restart interval */ enInfo->restartInRows=atoi(++arg); break; case 'v': /* * verbose flag */ *verbose=1; break; default: fprintf(stderr,"%s\n",usage); exit(-1); } } }}/* *-------------------------------------------------------------- * * StatOutput -- * * Display statistics data on screen. * * Results: * None. * * Side effects: * Compression statistics data are output to stderr. * *-------------------------------------------------------------- */voidStatOutput(enInfo) CompressInfo enInfo;{ int i,tbl; /* * The total bytes of category symbols and additional bits. */ fprintf(stderr,"PSV HuffSymSum AddBitsSum\n"); for (i=0;i<numSelValue;i++) { tbl=psvSet[i]-1; fprintf(stderr,"%3d %10ld %10ld\n", psvSet[i],totalHuffSym[tbl]/8,totalAddBits[tbl]/8); } /* * The PSV selected by our PSV selector. * The original and compressed image file size. * The compression ration (original/compressed). */ fprintf(stderr,"Selected PSV\t\t: %d\n",enInfo.Ss); fprintf(stderr,"Original file size\t: %ld bytes\n",inputFileBytes); fprintf(stderr,"Compressed file size\t: %ld bytes\n",outputFileBytes); fprintf(stderr,"Compression ratio\t:"); fprintf(stderr,"%5.2f\n",(float)inputFileBytes/(float)outputFileBytes);}intmain(argc, argv) int argc; char **argv;{ CompressInfo enInfo; JpegComponentInfo *compPtr; int i; FILE *inFile; int optimize; /* * Process command line parameters. */ MEMSET(&enInfo, 0, sizeof(enInfo)); ArgParser(&enInfo,argc,argv,&optimize,&verbose,&inFile,&outFile); if (verbose) { fprintf(stderr,"Point transform parameter is %d.\n",enInfo.Pt); fprintf(stderr,"Restart every %d row(s).\n",enInfo.restartInRows); } /* * Load the image and get ready for encoding. */ PmRead(&enInfo,inFile); fclose(inFile); HuffEncoderInit (&enInfo); /* * Get the Huffman tables ready. Select the best PSV to * be used in encoding pass. */ if (optimize) { /* * optimal encoding */ if (verbose) { fprintf(stderr,"Use optimal Huffman table.\n"); } /* * Assign a Huffman table to be used by a component. */ for (i = 0; i < enInfo.compsInScan; i++) { compPtr = enInfo.curCompInfo[i]; compPtr->dcTblNo=i; } /* * Count the times each difference category occurs. * Construct the optimal Huffman table, then select * the best PSV using optimal Huffman table. */ HuffOptimize (&enInfo); } else { /* * non-optimal encoding */ if (verbose) { fprintf(stderr,"Use default huffman table.\n"); } /* * Assign a Huffman table to be used by a component. * In non-optimal encoding, all components share one * stardard Huffman table. */ for (i = 0; i < enInfo.compsInScan; i++) { compPtr = enInfo.curCompInfo[i]; compPtr->dcTblNo=0; } /* * Load and prepare the standard Huffman table. */ LoadStdHuffTables(&enInfo); for (i = 0; i < enInfo.compsInScan; i++) { compPtr = enInfo.curCompInfo[i]; FixHuffTbl ((enInfo.dcHuffTblPtrs)[compPtr->dcTblNo]); } /* * Select the best PSV using standard Huffman table. */ if (numSelValue>1) { StdPickSelValue(&enInfo); } else { enInfo.Ss=psvSet[0]; } } /* * Write the frame and scan headers. Encode the image. * Clean up everything. Output statistics if verbose * flag is on. */ WriteFileHeader (&enInfo); WriteScanHeader (&enInfo); HuffEncode (&enInfo); FreeArray2D(mcuTable); HuffEncoderTerm (); WriteFileTrailer (&enInfo); FlushBytes (); fflush(outFile); if (ferror(outFile)) { fprintf (stderr, "Output file write error\n"); } fclose(outFile); if (verbose) { StatOutput(enInfo); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -