{
    "mode": "man",
    "parameter": "pnmtojpeg",
    "section": "1",
    "url": "https://www.chedong.com/phpMan.php/man/pnmtojpeg/1/json",
    "generated": "2026-05-30T07:34:14Z",
    "synopsis": "pnmtojpeg [ options ] [ filename ]",
    "sections": {
        "NAME": {
            "content": "pnmtojpeg - convert PNM image to a JFIF (\"JPEG\") image\n\n",
            "subsections": []
        },
        "SYNOPSIS": {
            "content": "pnmtojpeg [ options ] [ filename ]\n",
            "subsections": []
        },
        "DESCRIPTION": {
            "content": "pnmtojpeg converts the named PBM, PGM, or PPM image file, or the standard input if no file is\nnamed, to a JFIF file on the standard output.\n\npnmtojpeg uses the Independent JPEG Group's JPEG library to  create  the  output  file.   See\nhttp://www.ijg.org for information on the library.\n\n\"JFIF\" is the correct name for the image format commonly known as \"JPEG.\"  Strictly speaking,\nJPEG is a method of compression.  The image format using JPEG compression that is by far  the\nmost common is JFIF.  There is also a subformat of TIFF that uses JPEG compression.\n\nEXIF  is  an  image  format that is a subformat of JFIF (to wit, a JFIF file that contains an\nEXIF header as an APP1 marker).  pnmtojpeg creates an EXIF image when you specify  the  -exif\noption.\n\n",
            "subsections": []
        },
        "OPTIONS": {
            "content": "The basic options are:\n\n--exif=filespec\nThis  option specifies that the output image is to be EXIF (a subformat of JFIF), i.e.\nit will have an EXIF header as a JFIF APP1 marker.  The contents of  that  marker  are\nthe contents of the specified file.  The special value - means to read the EXIF header\ncontents from standard input.  It is invalid to specify standard input  for  both  the\nEXIF header and the input image.\n\nThe  EXIF file starts with a two byte field which is the length of the file, including\nthe length field, in pure binary, most significant byte first.  The special  value  of\nzero  for  the  length  field means there is to be no EXIF header, i.e. the same as no\n-exif option.  This is useful for when you convert a file from JFIF to PNM using jpeg‐‐\ntopnm,  then  transform it, then convert it back to JFIF with pnmtojpeg, and you don't\nknow whether or not it includes an EXIF header.  jpegtopnm creates an EXIF  file  con‐\ntaining  nothing  but  two  bytes of zero when the input JFIF file has no EXIF header.\nThus, you can transfer any EXIF header from the input JFIF to the output JFIF  without\nworrying about whether an EXIF header actually exists.\n\nThe  contents of the EXIF file after the length field are the exact byte for byte con‐\ntents of the APP1 marker, not counting the length field,  that  constitutes  the  EXIF\nheader.\n\n\n--quality=n\nScale  quantization tables to adjust image quality.  n is 0 (worst) to 100 (best); de‐\nfault is 75.  (See below for more info.)\n",
            "subsections": [
                {
                    "name": "--grayscale",
                    "content": "",
                    "long": "--grayscale"
                },
                {
                    "name": "--greyscale",
                    "content": "Create gray scale JFIF file.  With this option, pnmtojpeg converts color input to gray\nscale.   If  you  don't specify this option, The output file is in color format if the\ninput is PPM, and grayscale format if the input is PBM or PGM.\n\nIn the PPM input case, even if all the colors in the image are gray, the output is  in\ncolor  format.   Of  course,  the colors in it are still gray.  The difference is that\ncolor format takes up a lot more space and takes longer to create and process.\n",
                    "long": "--greyscale"
                },
                {
                    "name": "--optimize",
                    "content": "Perform optimization of entropy encoding parameters.  Without this, pnmtojpeg uses de‐\nfault  encoding  parameters.  --optimize usually makes the JFIF file a little smaller,\nbut pnmtojpeg runs somewhat slower and needs much  more  memory.   Image  quality  and\nspeed of decompression are unaffected by --optimize.\n",
                    "long": "--optimize"
                },
                {
                    "name": "--progressive",
                    "content": "Create a progressive JPEG file (see below).\n\n--comment=text\nInclude a comment marker in the JFIF output, with comment text text.  Without this op‐\ntion, there are no comment markers in the output.\n\n\nThe --quality option lets you trade off compressed file size against quality  of  the  recon‐\nstructed  image: the higher the quality setting, the larger the JFIF file, and the closer the\noutput image will be to the original input.  Normally you want to use the lowest quality set‐\nting  (smallest  file)  that  decompresses into something visually indistinguishable from the\noriginal image.  For this purpose the quality setting should be between 50 and  95;  the  de‐\nfault  of  75  is  often about right.  If you see defects at --quality=75, then go up 5 or 10\ncounts at a time until you are happy with the output image.  (The optimal setting  will  vary\nfrom one image to another.)\n\n--quality=100  generates a quantization table of all 1's, minimizing loss in the quantization\nstep (but there is still information loss in subsampling, as well as roundoff  error).   This\nsetting  is  mainly of interest for experimental purposes.  Quality values above about 95 are\nnot recommended for normal use; the compressed file size goes up dramatically for hardly  any\ngain in output image quality.\n\nIn  the  other  direction, quality values below 50 will produce very small files of low image\nquality.  Settings around 5 to 10 might be useful in preparing an index of a large image  li‐\nbrary, for example.  Try --quality=2 (or so) for some amusing Cubist effects.  (Note: quality\nvalues below about 25 generate 2-byte quantization tables, which are considered  optional  in\nthe JFIF standard.  pnmtojpeg emits a warning message when you give such a quality value, be‐\ncause some other JFIF programs may be unable to decode the resulting file.  Use --baseline if\nyou need to ensure compatibility at low quality values.)\n\nThe  --progressive  option creates a \"progressive JPEG\" file.  In this type of JFIF file, the\ndata is stored in multiple scans of increasing quality.  If the  file  is  being  transmitted\nover  a slow communications link, the decoder can use the first scan to display a low-quality\nimage very quickly, and can then improve the display with each subsequent  scan.   The  final\nimage  is exactly equivalent to a standard JFIF file of the same quality setting, and the to‐\ntal file size is about the same -- often a little smaller.  Caution: progressive JPEG is  not\nyet  widely  implemented,  so many decoders will be unable to view a progressive JPEG file at\nall.\n\nOptions for advanced users:\n",
                    "long": "--progressive"
                },
                {
                    "name": "--dct=int",
                    "content": "Use integer DCT method (default).\n",
                    "long": "--dct",
                    "arg": "int"
                },
                {
                    "name": "--dct=fast",
                    "content": "Use fast integer DCT (less accurate).\n",
                    "long": "--dct",
                    "arg": "fast"
                },
                {
                    "name": "--dct=float",
                    "content": "Use floating-point DCT method.  The float method is very slightly more  accurate  than\nthe  int  method,  but is much slower unless your machine has very fast floating-point\nhardware.  Also note that results of  the  floating-point  method  may  vary  slightly\nacross  machines,  while  the integer methods should give the same results everywhere.\nThe fast integer method is much less accurate than the other two.\n\n--restart=n\nEmit a JPEG restart marker every n MCU rows, or every n MCU blocks if you append B  to\nthe number.  --restart 0 (the default) means no restart markers.\n\n--smooth=n\nSmooth  the input image to eliminate dithering noise.  n, ranging from 1 to 100, indi‐\ncates the strength of smoothing.  0 (the default) means no smoothing.\n\n--maxmemory=n\nSet a limit for amount of memory to use in processing large images.  Value is in thou‐\nsands  of  bytes,  or  millions  of bytes if you append M to the number.  For example,\n--max=4m selects 4,000,000 bytes.  If pnmtojpeg needs more space, it will  use  tempo‐\nrary files.\n",
                    "long": "--dct",
                    "arg": "float"
                },
                {
                    "name": "--verbose",
                    "content": "Print  to  the Standard Error file messages about the conversion process.  This can be\nhelpful in debugging problems.\n\nThe --restart option tells pnmtojpeg to insert extra markers that allow  a  JPEG  decoder  to\nresynchronize  after  a  transmission  error.   Without restart markers, any damage to a com‐\npressed file will usually ruin the image from the point of the error to the end of the image;\nwith  restart  markers,  the damage is usually confined to the portion of the image up to the\nnext restart marker.  Of course, the  restart  markers  occupy  extra  space.   We  recommend\n--restart=1 for images that will be transmitted across unreliable networks such as Usenet.\n\nThe  --smooth  option  filters the input to eliminate fine-scale noise.  This is often useful\nwhen converting dithered images to JFIF:  a moderate smoothing factor of 10 to 50 gets rid of\ndithering  patterns  in the input file, resulting in a smaller JFIF file and a better-looking\nimage.  Too large a smoothing factor will visibly blur the image, however.\n\nOptions for wizards:\n",
                    "long": "--verbose"
                },
                {
                    "name": "--baseline",
                    "content": "Force baseline-compatible quantization tables to be generated.  This clamps  quantiza‐\ntion  values  to  8  bits even at low quality settings.  (This switch is poorly named,\nsince it does not ensure that the output is actually baseline JPEG.  For example,  you\ncan use --baseline and --progressive together.)\n\n--qtables=filespec\nUse the quantization tables given in the specified text file.\n",
                    "long": "--baseline"
                },
                {
                    "name": "--qslots=n[,...]",
                    "content": "Select which quantization table to use for each color component.\n\n--sample=HxV[,...]\nSet JPEG sampling factors for each color component.\n\n--scans=filespec\nUse  the  scan  script given in the specified text file.  See below for information on\nscan scripts.\n\nThe \"wizard\" options are intended for experimentation with JPEG.  If you don't know what  you\nare doing, don't use them.  These switches are documented further in the file wizard.doc that\ncomes with the Independent JPEG Group's JPEG library.\n",
                    "long": "--qslots",
                    "arg": "n[,...]"
                }
            ]
        },
        "EXAMPLES": {
            "content": "This example compresses the PPM file foo.ppm with a quality factor of 60 and saves the output\nas foo.jpg:\n\npnmtojpeg --quality=60 foo.ppm > foo.jpg\n\ncat foo.bmp | bmptoppm | pnmtojpeg > foo.jpg\n\n",
            "subsections": []
        },
        "HINTS": {
            "content": "JFIF is not ideal for cartoons, line drawings, and other images that have only a few distinct\ncolors.  For those, try instead pnmtopng or ppmtobmp.  If you need to convert such  an  image\nto JFIF, though, you should experiment with pnmtojpeg's --quality and --smooth options to get\na satisfactory conversion.  --smooth 10 or so is often helpful.\n\nJPEG compression is notable for being a \"lossy.\"  This means that, unlike with most  graphics\nconversions,  you  lose information, which means image quality, when you convert to JFIF.  If\nyou convert from PPM to JFIF and back repeatedly, image quality loss will accumulate.   After\nten or so cycles the image may be noticeably worse than it was after one cycle.\n\nBecause of this, you should do all the manipulation you have to do on the image in some other\nformat and convert to JFIF as the last step.  And if you can keep a copy in the original for‐\nmat, so much the better.  PNG is a good choice for a format that is lossless, yet fairly com‐\npact.  GIF is another way to go, but chances are you can't create a GIF image without owing a\nlot  of  money  to  Unisys and IBM, holders of patents on the LZW compression used in the GIF\nformat.\n\nThe --optimize option to pnmtojpeg is worth using when you are making a \"final\"  version  for\nposting  or  archiving.  It's also a win when you are using low quality settings to make very\nsmall JFIF files; the percentage improvement is often a lot more than it is on larger  files.\n(At  present, --optimize mode is automatically in effect when you generate a progressive JPEG\nfile).\n\nAnother program, cjpeg, is similar.  cjpeg is maintained by the Independent  JPEG  Group  and\npackaged  with the JPEG library which pnmtojpeg uses for all its JPEG work.  Because of that,\nyou may expect it to exploit more current JPEG features.  Also, since you have  to  have  the\nlibrary to run pnmtojpeg, but not vice versa, cjpeg may be more commonly available.\n\nOn  the  other hand, cjpeg does not use the NetPBM libraries to process its input, as all the\nNetPBM tools such as pnmtojpeg do.  This means it is less likely to be  consistent  with  all\nthe  other programs that deal with the NetPBM formats.  Also, the command syntax of pnmtojpeg\nis consistent with that of the other Netpbm tools, unlike cjpeg.\n\n",
            "subsections": []
        },
        "SCAN SCRIPTS": {
            "content": "Use the -scan option to specify a scan script.  Or use the -progressive option to  specify  a\nparticular built-in scan script.\n\nJust  what  a scan script is, and the basic format of the scan script file, is covered in the\nwizard.doc file that comes with the Independent JPEG Group's JPEG library.  Scan scripts  are\nsame for pnmtojpeg as the are for cjpeg.\n\nThis section contains additional information that isn't, but probably should be, in that doc‐\nument.\n\nFirst, there are many restrictions on what is a valid scan script.   The  JPEG  library,  and\nthus  pnmtojpeg,  checks  thoroughly  for any lack of compliance with these restrictions, but\ndoes little to tell you how the script fails to comply.  The messages are  very  general  and\nsometimes untrue.\n\nTo start with, the entries for the DC coefficient must come before any entries for the AC co‐\nefficients.  The DC coefficient is Coefficient 0; all the other coefficients are  AC  coeffi‐\ncients.  So in an entry for the DC coefficient, the two numbers after the colon must be 0 and\n0.  In an entry for AC coefficients, the first number after the colon must not be 0.\n\nIn a DC entry, the color components must be in increasing order.   E.g.  \"0,2,1\"  before  the\ncolon is wrong.  So is \"0,0,0\".\n\nIn  an  entry for an AC coeffient, you must specify only one color component.  I.e. there can\nbe only one number before the colon.\n\nIn the first entry for a particular coefficient for a particular color  component,  the  \"Ah\"\nvalue  must be zero, but the Al value can be any valid bit number.  In subsequent entries, Ah\nmust be the Al value from the previous entry (for that coefficient for that color component),\nand the Al value must be one less than the Ah value.\n\nThe  script must ultimately specify at least some of the DC coefficent for every color compo‐\nnent.  Otherwise, you get the error message \"Script does not transmit  all  the  data.\"   You\nneed not specify all of the bits of the DC coefficient, or any of the AC coefficients.\n\nThere  is  a standard option in building the JPEG library to omit scan script capability.  If\nfor some reason your library was built with this option, you get the message \"Requested  fea‐\nture was omitted at compile time.\"\n\n",
            "subsections": []
        },
        "ENVIRONMENT": {
            "content": "JPEGMEM\nIf this environment variable is set, its value is the default memory limit.  The value\nis specified as described for the --maxmemory option.  An explicit --maxmemory  option\noverrides any JPEGMEM.\n\n",
            "subsections": []
        },
        "SEE ALSO": {
            "content": "cjpeg(1), djpeg(1), jpegtran(1), rdjpgcom(1), wrjpgcom(1)\nppm(5), pgm(5), jpegtopnm(1)\nWallace,  Gregory  K.   \"The  JPEG Still Picture Compression Standard\", Communications of the\nACM, April 1991 (vol. 34, no. 4), pp. 30-44.\n",
            "subsections": []
        },
        "LIMITATIONS": {
            "content": "Arithmetic coding is not supported for legal reasons.\n\nThe program could be much faster.\n\n",
            "subsections": []
        },
        "AUTHOR": {
            "content": "pnmtojpeg and this man page were derived in large part from cjpeg, by  the  Independent  JPEG\nGroup.  The program is otherwise by Bryan Henderson on March 07, 2000.\n\n\n\n\n\n\n\n07 March 2000                               PNMTOJPEG(1)",
            "subsections": []
        }
    },
    "summary": "pnmtojpeg - convert PNM image to a JFIF (\"JPEG\") image",
    "flags": [
        {
            "flag": "",
            "long": "--grayscale",
            "arg": null,
            "description": ""
        },
        {
            "flag": "",
            "long": "--greyscale",
            "arg": null,
            "description": "Create gray scale JFIF file. With this option, pnmtojpeg converts color input to gray scale. If you don't specify this option, The output file is in color format if the input is PPM, and grayscale format if the input is PBM or PGM. In the PPM input case, even if all the colors in the image are gray, the output is in color format. Of course, the colors in it are still gray. The difference is that color format takes up a lot more space and takes longer to create and process."
        },
        {
            "flag": "",
            "long": "--optimize",
            "arg": null,
            "description": "Perform optimization of entropy encoding parameters. Without this, pnmtojpeg uses de‐ fault encoding parameters. --optimize usually makes the JFIF file a little smaller, but pnmtojpeg runs somewhat slower and needs much more memory. Image quality and speed of decompression are unaffected by --optimize."
        },
        {
            "flag": "",
            "long": "--progressive",
            "arg": null,
            "description": "Create a progressive JPEG file (see below). --comment=text Include a comment marker in the JFIF output, with comment text text. Without this op‐ tion, there are no comment markers in the output. The --quality option lets you trade off compressed file size against quality of the recon‐ structed image: the higher the quality setting, the larger the JFIF file, and the closer the output image will be to the original input. Normally you want to use the lowest quality set‐ ting (smallest file) that decompresses into something visually indistinguishable from the original image. For this purpose the quality setting should be between 50 and 95; the de‐ fault of 75 is often about right. If you see defects at --quality=75, then go up 5 or 10 counts at a time until you are happy with the output image. (The optimal setting will vary from one image to another.) --quality=100 generates a quantization table of all 1's, minimizing loss in the quantization step (but there is still information loss in subsampling, as well as roundoff error). This setting is mainly of interest for experimental purposes. Quality values above about 95 are not recommended for normal use; the compressed file size goes up dramatically for hardly any gain in output image quality. In the other direction, quality values below 50 will produce very small files of low image quality. Settings around 5 to 10 might be useful in preparing an index of a large image li‐ brary, for example. Try --quality=2 (or so) for some amusing Cubist effects. (Note: quality values below about 25 generate 2-byte quantization tables, which are considered optional in the JFIF standard. pnmtojpeg emits a warning message when you give such a quality value, be‐ cause some other JFIF programs may be unable to decode the resulting file. Use --baseline if you need to ensure compatibility at low quality values.) The --progressive option creates a \"progressive JPEG\" file. In this type of JFIF file, the data is stored in multiple scans of increasing quality. If the file is being transmitted over a slow communications link, the decoder can use the first scan to display a low-quality image very quickly, and can then improve the display with each subsequent scan. The final image is exactly equivalent to a standard JFIF file of the same quality setting, and the to‐ tal file size is about the same -- often a little smaller. Caution: progressive JPEG is not yet widely implemented, so many decoders will be unable to view a progressive JPEG file at all. Options for advanced users:"
        },
        {
            "flag": "",
            "long": "--dct",
            "arg": "int",
            "description": "Use integer DCT method (default)."
        },
        {
            "flag": "",
            "long": "--dct",
            "arg": "fast",
            "description": "Use fast integer DCT (less accurate)."
        },
        {
            "flag": "",
            "long": "--dct",
            "arg": "float",
            "description": "Use floating-point DCT method. The float method is very slightly more accurate than the int method, but is much slower unless your machine has very fast floating-point hardware. Also note that results of the floating-point method may vary slightly across machines, while the integer methods should give the same results everywhere. The fast integer method is much less accurate than the other two. --restart=n Emit a JPEG restart marker every n MCU rows, or every n MCU blocks if you append B to the number. --restart 0 (the default) means no restart markers. --smooth=n Smooth the input image to eliminate dithering noise. n, ranging from 1 to 100, indi‐ cates the strength of smoothing. 0 (the default) means no smoothing. --maxmemory=n Set a limit for amount of memory to use in processing large images. Value is in thou‐ sands of bytes, or millions of bytes if you append M to the number. For example, --max=4m selects 4,000,000 bytes. If pnmtojpeg needs more space, it will use tempo‐ rary files."
        },
        {
            "flag": "",
            "long": "--verbose",
            "arg": null,
            "description": "Print to the Standard Error file messages about the conversion process. This can be helpful in debugging problems. The --restart option tells pnmtojpeg to insert extra markers that allow a JPEG decoder to resynchronize after a transmission error. Without restart markers, any damage to a com‐ pressed file will usually ruin the image from the point of the error to the end of the image; with restart markers, the damage is usually confined to the portion of the image up to the next restart marker. Of course, the restart markers occupy extra space. We recommend --restart=1 for images that will be transmitted across unreliable networks such as Usenet. The --smooth option filters the input to eliminate fine-scale noise. This is often useful when converting dithered images to JFIF: a moderate smoothing factor of 10 to 50 gets rid of dithering patterns in the input file, resulting in a smaller JFIF file and a better-looking image. Too large a smoothing factor will visibly blur the image, however. Options for wizards:"
        },
        {
            "flag": "",
            "long": "--baseline",
            "arg": null,
            "description": "Force baseline-compatible quantization tables to be generated. This clamps quantiza‐ tion values to 8 bits even at low quality settings. (This switch is poorly named, since it does not ensure that the output is actually baseline JPEG. For example, you can use --baseline and --progressive together.) --qtables=filespec Use the quantization tables given in the specified text file."
        },
        {
            "flag": "",
            "long": "--qslots",
            "arg": "n[,...",
            "description": "Select which quantization table to use for each color component. --sample=HxV[,...] Set JPEG sampling factors for each color component. --scans=filespec Use the scan script given in the specified text file. See below for information on scan scripts. The \"wizard\" options are intended for experimentation with JPEG. If you don't know what you are doing, don't use them. These switches are documented further in the file wizard.doc that comes with the Independent JPEG Group's JPEG library."
        }
    ],
    "examples": [
        "This example compresses the PPM file foo.ppm with a quality factor of 60 and saves the output",
        "as foo.jpg:",
        "pnmtojpeg --quality=60 foo.ppm > foo.jpg",
        "cat foo.bmp | bmptoppm | pnmtojpeg > foo.jpg"
    ],
    "see_also": [
        {
            "name": "cjpeg",
            "section": "1",
            "url": "https://www.chedong.com/phpMan.php/man/cjpeg/1/json"
        },
        {
            "name": "djpeg",
            "section": "1",
            "url": "https://www.chedong.com/phpMan.php/man/djpeg/1/json"
        },
        {
            "name": "jpegtran",
            "section": "1",
            "url": "https://www.chedong.com/phpMan.php/man/jpegtran/1/json"
        },
        {
            "name": "rdjpgcom",
            "section": "1",
            "url": "https://www.chedong.com/phpMan.php/man/rdjpgcom/1/json"
        },
        {
            "name": "wrjpgcom",
            "section": "1",
            "url": "https://www.chedong.com/phpMan.php/man/wrjpgcom/1/json"
        },
        {
            "name": "ppm",
            "section": "5",
            "url": "https://www.chedong.com/phpMan.php/man/ppm/5/json"
        },
        {
            "name": "pgm",
            "section": "5",
            "url": "https://www.chedong.com/phpMan.php/man/pgm/5/json"
        },
        {
            "name": "jpegtopnm",
            "section": "1",
            "url": "https://www.chedong.com/phpMan.php/man/jpegtopnm/1/json"
        }
    ]
}