Esempio n. 1
0
int 
main(int argc, const char **argv) {

    struct CmdlineInfo cmdline;
    struct pam * imgPam;  /* malloced */
    struct pam outimg;
    unsigned int fileCt;
    Coord * coords;  /* malloced */
    FILE * headerFileP;
    FILE * dataFileP;
    const char ** names; /* malloced */
    unsigned int qfactor;  /* In per cent */

    pm_proginit(&argc, argv);

    parseCommandLine(argc, argv, &cmdline);

    headerFileP = cmdline.header ? pm_openw(cmdline.header) : NULL;
    dataFileP = cmdline.data ? pm_openw(cmdline.data) : NULL;

    qfactor = qfactorFromQuality(cmdline.quality, cmdline.quality2);

    openFiles(cmdline, &fileCt, &imgPam, &names);

    readFileHeaders(imgPam, fileCt);

    sortImagesByArea(fileCt, imgPam, names);

    findpack(imgPam, fileCt, &coords, cmdline.quality2, qfactor);

    computeOutputType(&outimg.maxval, &outimg.format, outimg.tuple_type,
                      &outimg.depth, fileCt, imgPam);

    computeOutputDimensions(&outimg.width, &outimg.height, fileCt,
                            imgPam, coords);
    outimg.size = sizeof(outimg);
    outimg.len = PAM_STRUCT_SIZE(allocation_depth);
    pnm_setminallocationdepth(&outimg, outimg.depth);
    outimg.plainformat = false;
    outimg.file = stdout;
 
    writePam(&outimg, fileCt, coords, imgPam);

    if (dataFileP)
        writeData(dataFileP, outimg.width, outimg.height,
                  fileCt, names, coords, imgPam);

    if (headerFileP)
        writeHeader(headerFileP, cmdline.prefix, outimg.width, outimg.height,
                    fileCt, names, coords, imgPam);

    closeFiles(imgPam, fileCt, headerFileP, dataFileP);

    free(coords);
    free(imgPam);
    free(names);

    return 0;
}
Esempio n. 2
0
static void
extract_one_image(FILE *infile, const char outputfilename[]) {

    FILE *outfile;
    xelval maxval;
    int rows, cols, format;
    enum pm_check_code check_retval;
    
    int row;
    xel *xelrow;

    pnm_readpnminit(infile, &cols, &rows, &maxval, &format);

    pnm_check(infile, PM_CHECK_BASIC, format, cols, rows, maxval, 
              &check_retval);

    outfile = pm_openw(outputfilename);
    pnm_writepnminit(outfile, cols, rows, maxval, format, 0);

    xelrow = pnm_allocrow(cols);
    for (row = 0; row < rows; row++) {
        pnm_readpnmrow(infile, xelrow, cols, maxval, format);
        pnm_writepnmrow(outfile, xelrow, cols, maxval, format, 0);
    }
    pnm_freerow(xelrow);
    pm_close(outfile);
}
Esempio n. 3
0
int
main(int argc, char ** argv) {

    struct cmdlineInfo cmdline;
    FILE * convFileP;
    const char * tempfileName;

    pnm_init(&argc, argv);

    parseCommandLine(argc, argv, &cmdline);

    if (cmdline.dump)
        convFileP = pm_openw(cmdline.dump);
    else
        pm_make_tmpfile(&convFileP, &tempfileName);
        
    writeConvolutionImage(convFileP, cmdline.width, cmdline.height,
                          PGM_FORMAT);

    pm_close(convFileP);

    if (cmdline.dump) {
        /* We're done.  Convolution image is in user's file */
    } else {
        pm_system_lp("pnmconvol", NULL, NULL, NULL, NULL,
                     "pnmconvol", tempfileName, cmdline.inputFilespec, NULL);

        unlink(tempfileName);
        strfree(tempfileName);
    }
    return 0;
}
Esempio n. 4
0
static void 
writeMS_Ico(MS_Ico       const MSIconData, 
            const char * const outFname) {
    int x,y;
   
    ofp = pm_openw(outFname);

    writeU2(MSIconData->reserved);
    writeU2(MSIconData->type);
    writeU2(MSIconData->count);
    for (x=0;x<MSIconData->count;x++) writeIC_Entry(MSIconData->entries[x]);
    for (x=0;x<MSIconData->count;x++) {
        writeIC_InfoHeader(MSIconData->entries[x]->ih);
        for (y=0;y<(MSIconData->entries[x]->color_count);y++) {
            writeIC_Color(MSIconData->entries[x]->colors[y]);
        }
        if (verbose) pm_message("writing xor bitmap");
        writeBitmap(MSIconData->entries[x]->xorBitmapOut,
                    MSIconData->entries[x]->xBytesXor,
                    MSIconData->entries[x]->height);
        if (verbose) pm_message("writing and bitmap");
        writeBitmap(MSIconData->entries[x]->andBitmapOut,
                    MSIconData->entries[x]->xBytesAnd,
                    MSIconData->entries[x]->height);
    }
    fclose(ofp);
}
Esempio n. 5
0
static void
writeMap(const char * const wmapFileName,
         const gray * const lumamap,
         xelval       const maxval) {

    FILE * const wmapfP = pm_openw(wmapFileName);

    pgm_writepgminit(wmapfP, maxval+1, 1, maxval, 0);

    pgm_writepgmrow(wmapfP, lumamap, maxval+1, maxval, 0);

    pm_close(wmapfP);
}
Esempio n. 6
0
int
main(int argc, char *argv[]) {

    FILE *ifp;
    FILE *alpha_file, *imageout_file;
    pixel *colormap;
    int cols, rows;
    int transparent;  /* value of 'data' that means transparent */
    int *data;
        /* The image as an array of width * height integers, each one
           being an index int colormap[].
        */

    struct cmdline_info cmdline;

    ppm_init(&argc, argv);

    parse_command_line(argc, argv, &cmdline);

    verbose = cmdline.verbose;

    if ( cmdline.input_filespec != NULL ) 
        ifp = pm_openr( cmdline.input_filespec);
    else
        ifp = stdin;

    if (cmdline.alpha_stdout)
        alpha_file = stdout;
    else if (cmdline.alpha_filename == NULL) 
        alpha_file = NULL;
    else {
        alpha_file = pm_openw(cmdline.alpha_filename);
    }

    if (cmdline.alpha_stdout) 
        imageout_file = NULL;
    else
        imageout_file = stdout;

    ReadXPMFile(ifp, &cols, &rows, &colormap, &data, &transparent);
    
    pm_close(ifp);

    writeOutput(imageout_file, alpha_file, cols, rows, colormap, data,
                transparent);

    free(colormap);
    
    return 0;
}
Esempio n. 7
0
static void
writeText(IPDB *       const pdbP,
          const char * const name) {

    const char * const note = ipdb_text(pdbP);

    FILE * fP;

    if (name == NULL || note == NULL) {
    } else {
        fP = pm_openw(name);
        if (fP == NULL)
            pm_error("Could not open note file '%s' for output", name);
        
        fprintf(fP, "%s\n", note);

        pm_close(fP);
    }
}
Esempio n. 8
0
static void
save_exif(struct jpeg_decompress_struct const cinfo, 
          const char *                  const exif_filespec) {
/*----------------------------------------------------------------------------
  Write the contents of the first Exif header in the image into the
  file with filespec 'exif_filespec'.  Start with the two byte length
  field.  If 'exif_filespec' is "-", write to standard output.

  If there is no Exif header in the image, write just zero, as a two
  byte pure binary integer.
-----------------------------------------------------------------------------*/
    FILE * exif_file;
    struct jpeg_marker_struct * markerP;

    exif_file = pm_openw(exif_filespec);

    for (markerP = cinfo.marker_list; 
         markerP && !is_exif(*markerP);
         markerP = markerP->next);

    if (markerP) {
        pm_writebigshort(exif_file, markerP->data_length+2);
        if (ferror(exif_file))
            pm_error("Write of Exif header to %s failed on first byte.",
                     exif_filespec);
        else {
            int rc;

            rc = fwrite(markerP->data, 1, markerP->data_length, exif_file);
            if (rc != markerP->data_length)
                pm_error("Write of Exif header to '%s' failed.  Wrote "
                         "length successfully, but then failed after "
                         "%d characters of data.", exif_filespec, rc);
        }
    } else {
        /* There is no Exif header in the image */
        pm_writebigshort(exif_file, 0);
        if (ferror(exif_file))
            pm_error("Write of Exif header file '%s' failed.", exif_filespec);
    }
    pm_close(exif_file);
}
Esempio n. 9
0
int
main(int argc, char *argv[]) {

    struct cmdlineInfo cmdline;

    FILE * ifP;
    bool eof;  /* No more images in input */
    unsigned int imageSeq;  
        /* Sequence of current image in input file.  First = 0 */

    pnm_init(&argc, argv);

    parseCommandLine(argc, argv, &cmdline);
    
    ifP = pm_openr(cmdline.inputFileName);

    eof = FALSE;
    for (imageSeq = 0; !eof; ++imageSeq) {
        FILE * ofP;
        const char * outputFileName;  /* malloc'ed */

        computeOutputName(cmdline.outputFilePattern, cmdline.padname, 
                          imageSeq,
                          &outputFileName);
        pm_message("WRITING %s", outputFileName);

        ofP = pm_openw(outputFileName);
        extractOneImage(ifP, ofP);

        pm_close(ofP);
        strfree(outputFileName);

        pnm_nextimage(ifP, &eof);
    }
    pm_close(ifP);
    
    return 0;
}
Esempio n. 10
0
int
main(int argc, const char *argv[]) {

    struct cmdlineInfo cmdline;
    FILE * underlayFileP;
    FILE * overlayFileP;
    FILE * alphaFileP;
    struct pam underlayPam;
    struct pam overlayPam;
    struct pam alphaPam;
    struct pam composedPam;
    int originLeft, originTop;

    pm_proginit(&argc, argv);

    parseCommandLine(argc, argv, &cmdline);

    overlayFileP = pm_openr(cmdline.overlayFilespec);

    overlayPam.comment_p = NULL;
    pnm_readpaminit(overlayFileP, &overlayPam, 
                    PAM_STRUCT_SIZE(opacity_plane));

    if (overlayPam.len < PAM_STRUCT_SIZE(opacity_plane))
        pm_error("Libnetpbm is too old.  This program requires libnetpbm from "
                 "Netpbm 10.56 (September 2011) or newer");

    if (!overlayPam.visual)
        pm_error("Overlay image has tuple type '%s', which is not a "
                 "standard visual type.  We don't know how to compose.",
                 overlayPam.tuple_type);

    initAlphaFile(cmdline, &overlayPam, &alphaFileP, &alphaPam);

    underlayFileP = pm_openr(cmdline.underlyingFilespec);

    underlayPam.comment_p = NULL;
    pnm_readpaminit(underlayFileP, &underlayPam, 
                    PAM_STRUCT_SIZE(opacity_plane));

    assert(underlayPam.len >= PAM_STRUCT_SIZE(opacity_plane));

    if (!overlayPam.visual)
        pm_error("Overlay image has tuple type '%s', which is not a "
                 "standard visual type.  We don't know how to compose.",
                 overlayPam.tuple_type);
    
    computeOverlayPosition(underlayPam.width, underlayPam.height, 
                           overlayPam.width,  overlayPam.height,
                           cmdline, &originLeft, &originTop);

    composedPam.size             = PAM_STRUCT_SIZE(opacity_plane);
    composedPam.len              = PAM_STRUCT_SIZE(allocation_depth);
    composedPam.allocation_depth = 0;
    composedPam.file             = pm_openw(cmdline.outputFilespec);
    composedPam.comment_p        = NULL;

    determineOutputType(&underlayPam, &overlayPam, &composedPam);

    pnm_setminallocationdepth(&underlayPam, composedPam.depth);
    pnm_setminallocationdepth(&overlayPam,  composedPam.depth);
    
    composite(originLeft, originTop,
              &underlayPam, &overlayPam, alphaFileP ? &alphaPam : NULL,
              cmdline.alphaInvert, cmdline.opacity,
              &composedPam, cmdline.linear, cmdline.mixtransparency);

    if (alphaFileP)
        pm_close(alphaFileP);
    pm_close(overlayFileP);
    pm_close(underlayFileP);
    pm_close(composedPam.file);

    /* If the program failed, it previously aborted with nonzero completion
       code, via various function calls.
    */
    return 0;
}
Esempio n. 11
0
int 
main(int argc, char **argv)
{
  struct pam *imgs;
  struct pam outimg;
  struct pam p;
  int nfiles;
  int i, j;
  unsigned int q[10];
  coord *coords;
  const char *headfname = NULL;
  const char *datafname = NULL;
  const char *prefix = "";
  FILE *header;
  FILE *data;
  char **names;
  char *c;

  optEntry *option_def = malloc(100*sizeof(optEntry));
      /* Instructions to OptParseOptions3 on how to parse our options.
       */
  optStruct3 opt;

  unsigned int option_def_index;

  option_def_index = 0;   /* incremented by OPTENTRY */
  OPTENT3( 0,  "data",    OPT_STRING, &datafname, NULL, 0);
  OPTENT3( 0,  "header",  OPT_STRING, &headfname, NULL, 0);
  OPTENT3('q', "quality", OPT_UINT,   &qfactor,   NULL, 0);
  OPTENT3('p', "prefix",  OPT_STRING, &prefix,    NULL, 0);
  OPTENT3('0', "0",       OPT_FLAG,   NULL, &q[0],      0);
  OPTENT3('1', "1",       OPT_FLAG,   NULL, &q[1],      0);
  OPTENT3('2', "2",       OPT_FLAG,   NULL, &q[2],      0);
  OPTENT3('3', "3",       OPT_FLAG,   NULL, &q[3],      0);
  OPTENT3('4', "4",       OPT_FLAG,   NULL, &q[4],      0);
  OPTENT3('5', "5",       OPT_FLAG,   NULL, &q[5],      0);
  OPTENT3('6', "6",       OPT_FLAG,   NULL, &q[6],      0);
  OPTENT3('7', "7",       OPT_FLAG,   NULL, &q[7],      0);
  OPTENT3('8', "8",       OPT_FLAG,   NULL, &q[8],      0);
  OPTENT3('9', "9",       OPT_FLAG,   NULL, &q[9],      0);

  opt.opt_table = option_def;
  opt.short_allowed = FALSE;
  opt.allowNegNum = FALSE;

  pnm_init(&argc, argv);

  /* Check for flags. */
  optParseOptions3(&argc, argv, opt, sizeof(opt), 0);

  if (headfname)
    header = pm_openw(headfname);

  if (datafname)
    data = pm_openw(datafname);

  for (i = 0; i < 10; ++i)
  {
    if (q[i])
    {
      quality = i;
      switch (quality)
      {
        case 0: case 1: break;
        case 2: case 3: case 4: case 5: case 6: 
            qfactor = 100 * (8 - quality); 
            break;
        case 7: qfactor = 150; break;
        case 8: qfactor = 125; break;
        case 9: qfactor = 100; break;
      }
    }
  }

  if (1 < argc)
    nfiles = argc - 1;
  else
    nfiles = 1;

  MALLOCARRAY(imgs, nfiles);
  MALLOCARRAY(coords, nfiles);
  MALLOCARRAY(names, nfiles);
  
  if (!imgs || !coords || !names)
    pm_error("out of memory");

  if (1 < argc)
  {
    for (i = 0; i < nfiles; ++i)
    {
      if (strchr(argv[i+1], ':'))
      {
        imgs[i].file = pm_openr(strchr(argv[i+1], ':') + 1);
        *strchr(argv[i+1], ':') = 0;
        names[i] = argv[i+1];
      }
      else
      {
        imgs[i].file = pm_openr(argv[i+1]);
        names[i] = argv[i+1];
      }
    }
  }
  else
  {
    imgs[0].file = stdin;
  }

  pnm_readpaminit(imgs[0].file, &imgs[0], PAM_STRUCT_SIZE(tuple_type));
  outimg.maxval = imgs[0].maxval;
  outimg.format = imgs[0].format;
  memcpy(outimg.tuple_type, imgs[0].tuple_type, sizeof(imgs[0].tuple_type));
  outimg.depth = imgs[0].depth;

  for (i = 1; i < nfiles; ++i)
  {
    pnm_readpaminit(imgs[i].file, &imgs[i], PAM_STRUCT_SIZE(tuple_type));
    if (PAM_FORMAT_TYPE(imgs[i].format) > PAM_FORMAT_TYPE(outimg.format))
      outimg.format = imgs[i].format,
      memcpy(outimg.tuple_type, imgs[i].tuple_type, 
             sizeof(imgs[i].tuple_type));
    outimg.maxval = imax(imgs[i].maxval, outimg.maxval);
    outimg.depth = imax(imgs[i].depth, outimg.depth);
  }

  for (i = 0; i < nfiles - 1; ++i)
    for (j = i + 1; j < nfiles; ++j)
      if (imgs[j].width * imgs[j].height > imgs[i].width * imgs[i].height)
        p = imgs[i], imgs[i] = imgs[j], imgs[j] = p,
        c = names[i], names[i] = names[j], names[j] = c;

  findpack(imgs, nfiles, coords);

  outimg.height = outimg.width = 0;
  for (i = 0; i < nfiles; ++i)
  {
    outimg.width = imax(outimg.width, imgs[i].width + coords[i].x);
    outimg.height = imax(outimg.height, imgs[i].height + coords[i].y);
  }

  outimg.size = sizeof(outimg);
  outimg.len = sizeof(outimg);
  outimg.file = stdout;
  outimg.bytes_per_sample = 0;
  for (i = outimg.maxval; i; i >>= 8)
    ++outimg.bytes_per_sample;

  writePam(&outimg, nfiles, coords, imgs);

  if (datafname)
  {
    fprintf(data, ":0:0:%u:%u\n", outimg.width, outimg.height);

    for (i = 0; i < nfiles; ++i)
    {
      fprintf(data, "%s:%u:%u:%u:%u\n", names[i], coords[i].x,
          coords[i].y, imgs[i].width, imgs[i].height);
    }
  }

  if (headfname)
  {
    fprintf(header, "#define %sOVERALLX %u\n"
                    "#define %sOVERALLY %u\n"
                    "\n",
                    prefix, outimg.width,
                    prefix, outimg.height);

    for (i = 0; i < nfiles; ++i)
    {
      *strchr(names[i], '.') = 0;
      for (j = 0; names[i][j]; ++j)
      {
        if (ISLOWER(names[i][j]))
          names[i][j] = TOUPPER(names[i][j]);
      }
      fprintf(header, "#define %s%sX %u\n"
                      "#define %s%sY %u\n"
                      "#define %s%sSZX %u\n"
                      "#define %s%sSZY %u\n"
                      "\n",
                      prefix, names[i], coords[i].x,
                      prefix, names[i], coords[i].y,
                      prefix, names[i], imgs[i].width,
                      prefix, names[i], imgs[i].height);
    }
  }

  for (i = 0; i < nfiles; ++i)
    pm_close(imgs[i].file);
  pm_close(stdout);

  if (headfname)
    pm_close(header);

  if (datafname)
    pm_close(data);

  return 0;
}
Esempio n. 12
0
int
main(int argc, char *argv[]) {

    struct cmdlineInfo cmdline;
    FILE * underlayFileP;
    FILE * overlayFileP;
    FILE * alphaFileP;
    struct pam underlayPam;
    struct pam overlayPam;
    struct pam alphaPam;
    struct pam composedPam;
    int originLeft, originTop;

    pnm_init(&argc, argv);

    parseCommandLine(argc, argv, &cmdline);

    overlayFileP = pm_openr(cmdline.overlayFilespec);
    pnm_readpaminit(overlayFileP, &overlayPam, 
                    PAM_STRUCT_SIZE(allocation_depth));
    if (cmdline.alphaFilespec) {
        alphaFileP = pm_openr(cmdline.alphaFilespec);
        pnm_readpaminit(alphaFileP, &alphaPam, 
                        PAM_STRUCT_SIZE(allocation_depth));

        if (overlayPam.width != alphaPam.width || 
            overlayPam.height != alphaPam.height)
            pm_error("Opacity map and overlay image are not the same size");
    } else
        alphaFileP = NULL;

    underlayFileP = pm_openr(cmdline.underlyingFilespec);

    pnm_readpaminit(underlayFileP, &underlayPam, 
                    PAM_STRUCT_SIZE(allocation_depth));

    computeOverlayPosition(underlayPam.width, underlayPam.height, 
                           overlayPam.width,  overlayPam.height,
                           cmdline, &originLeft, &originTop);

    composedPam.size             = sizeof(composedPam);
    composedPam.len              = PAM_STRUCT_SIZE(allocation_depth);
    composedPam.allocation_depth = 0;
    composedPam.file             = pm_openw(cmdline.outputFilespec);

    determineOutputType(&composedPam, &underlayPam, &overlayPam);

    pnm_setminallocationdepth(&underlayPam, composedPam.depth);
    pnm_setminallocationdepth(&overlayPam,  composedPam.depth);
    
    composite(originLeft, originTop,
              &underlayPam, &overlayPam, alphaFileP ? &alphaPam : NULL,
              cmdline.alphaInvert, cmdline.opacity,
              &composedPam, cmdline.linear);

    if (alphaFileP)
        pm_close(alphaFileP);
    pm_close(overlayFileP);
    pm_close(underlayFileP);
    pm_close(composedPam.file);

    /* If the program failed, it previously aborted with nonzero completion
       code, via various function calls.
    */
    return 0;
}
Esempio n. 13
0
int main(int argc, char *argv[]) {
    FILE *fp, *fp_out;
    gray maxval;
    int format;
    int width = 0;
    int height = 0;
    int i, j;
    gray **pgm_data;
    int threshold = 127;
    
    int c;
    extern char *optarg;
    extern int optind;

    while((c = getopt(argc, argv, "t:")) != EOF) {
        switch( c ) {
            case 't':
                sscanf(optarg, "%d", &threshold);
                break;
		}
	}

//    printf("argc: %d\n", argc);
//    printf("optind: %d\n", optind);
//    printf("threshold: %d\n", threshold);

    // optind -- index in argv of the first argv-element that is not an option
    if((argc - optind) != 2) {
        fprintf(stderr, "Usage error\n");
        fprintf(stderr, "Usage: %s <input image> <output image>\n", argv[0]);
        fprintf(stderr, "Option:\n");
        fprintf(stderr, "-t <threshold>\n");

        exit(1);
    }

    // all PGM programs must call pgm_init() just after invocation, 
    // before they process their arguments.
    pgm_init(&argc, argv);

    // PBM function for reading, which is almost equivalent 
    // to f = fopen(filename, "rb");
    fp = pm_openr(argv[optind]);

    // read the PGM image header
    pgm_readpgminit(fp, &width, &height, &maxval, &format);

    printf("Succesfully read the header!\n\n");
    printf("= PGM image information =\n");
    printf("Width: %d\n", width);
    printf("Height: %d\n", height);
    printf("Max color: %d\n", maxval);
//    printf("Format: %c\n\n", PGM_FORMAT_TYPE(format));

    // close then open file again for reading data
    fclose(fp);
    fp = pm_openr(argv[optind]);
    
    pgm_data = pgm_readpgm(fp, &width, &height, &maxval);
    
    printf("Succesfully get the PGM image data!\n\n");

    tImage img;
    img.width = width;
    img.height = height;
    img.pixelType = GRAY8;
    img.pPixel = (UCHAR *)malloc(width * height * sizeof(UCHAR));

    // copy data to our format
    for(i = 0; i < height; i++) {
        for(j = 0; j < width; j++) {
            img.pPixel[i * width + j] = pgm_data[i][j];
        }
    }

    img = binarize(img, threshold);

    // convert back to the pgm format
    for(i = 0; i < height; i++) {
        for(j = 0; j < width; j++) {
            pgm_data[i][j] = img.pPixel[i * width + j];
        }
    }

    fp_out = pm_openw(argv[optind + 1]);

    // forceplain is a logical value that tells pgm_writepgminit() to 
    // write a header for a plain PGM format file, as opposed to a raw 
    // PGM format file.
    // 1 -> not a binary format
    int forceplain = 0;
    pgm_writepgm(fp_out, pgm_data, width, height, maxval, forceplain);
    
    printf("Succesfully write the binarized PGM image to disk!\n\n");

    free(img.pPixel);
    fclose(fp);
    fclose(fp_out);

    return 1;
}
Esempio n. 14
0
int
main(int argc, const char ** argv) {

    FILE * ifP;
    FILE *vf, *uf, *yf;
    pixel *pixelrow1, *pixelrow2;
    int rows, cols;
    int format;
    unsigned int row;
    pixval maxval;
    unsigned char *y1buf, *y2buf, *ubuf, *vbuf;
    struct FileNameSet fname;
        /* Output file names - .U, .V, .Y */

    pm_proginit(&argc, argv);

    if ((argc-1 > 2) || (argc-1 < 1))
        pm_error("Wrong number of arguments: %u.  "
                 "Arguments are basename for output files "
                 "and optional input file name", argc-1);

    if (argc-1 == 2)
        ifP = pm_openr(argv[2]);
    else
        ifP = stdin;

    makeOutputFileName(argv[1], &fname);

    uf = pm_openw(fname.u);
    vf = pm_openw(fname.v);
    yf = pm_openw(fname.y);

    termFileNameSet(fname);

    ppm_readppminit(ifP, &cols, &rows, &maxval, &format);

    if (cols % 2 == 1)
        pm_message("Warning: odd columns count %u, excess ignored", cols);

    if (rows % 2 == 1)
        pm_message("Warning: odd rows count %u, excess ignored", rows);

    pixelrow1 = ((pixel*) pm_allocrow(cols, sizeof(pixel)));
    pixelrow2 = ((pixel*) pm_allocrow(cols, sizeof(pixel)));

    y1buf = (unsigned char *) pm_allocrow(cols, 1);
    y2buf = (unsigned char *) pm_allocrow(cols, 1);
    ubuf = (unsigned char *) pm_allocrow(cols, 1);
    vbuf = (unsigned char *) pm_allocrow(cols, 1);

    for (row = 0; row < (rows & ~1); row += 2) {
        unsigned char *y1ptr, *y2ptr, *uptr, *vptr;
        pixel *pP1, *pP2;
        unsigned int col;

        ppm_readppmrow(ifP, pixelrow1, cols, maxval, format);
        ppm_readppmrow(ifP, pixelrow2, cols, maxval, format);

        pP1 = &pixelrow1[0]; pP2 = &pixelrow2[0];
        y1ptr = y1buf; y2ptr = y2buf; vptr = vbuf; uptr = ubuf;

        for (col = 0 ; col < (cols & ~1); col += 2) {
            pixval r0,g0,b0,r1,g1,b1,r2,g2,b2,r3,g3,b3;
            myLONG u, v, y0, y1, y2, y3, u0, u1, u2, u3, v0, v1, v2, v3;

            /* first pixel */
            r0 = PPM_GETR(*pP1);
            g0 = PPM_GETG(*pP1);
            b0 = PPM_GETB(*pP1);
            pP1++;
            /* 2nd pixel */
            r1 = PPM_GETR(*pP1);
            g1 = PPM_GETG(*pP1);
            b1 = PPM_GETB(*pP1);
            pP1++;
            /* 3rd pixel */
            r2 = PPM_GETR(*pP2);
            g2 = PPM_GETG(*pP2);
            b2 = PPM_GETB(*pP2);
            pP2++;
            /* 4th pixel */
            r3 = PPM_GETR(*pP2);
            g3 = PPM_GETG(*pP2);
            b3 = PPM_GETB(*pP2);
            pP2++;


            /* The JFIF RGB to YUV Matrix for $00010000 = 1.0

               [Y]   [19595   38469    7471][R]
               [U] = [-11056  -21712  32768][G]
               [V]   [32768   -27440  -5328][B]

            */

            y0 =  19595 * r0 + 38469 * g0 +  7471 * b0;
            u0 = -11056 * r0 - 21712 * g0 + 32768 * b0;
            v0 =  32768 * r0 - 27440 * g0 -  5328 * b0;

            y1 =  19595 * r1 + 38469 * g1 +  7471 * b1;
            u1 = -11056 * r1 - 21712 * g1 + 32768 * b1;
            v1 =  32768 * r1 - 27440 * g1 -  5328 * b1;

            y2 =  19595 * r2 + 38469 * g2 +  7471 * b2;
            u2 = -11056 * r2 - 21712 * g2 + 32768 * b2;
            v2 =  32768 * r2 - 27440 * g2 -  5328 * b2;

            y3 =  19595 * r3 + 38469 * g3 +  7471 * b3;
            u3 = -11056 * r3 - 21712 * g3 + 32768 * b3;
            v3 =  32768 * r3 - 27440 * g3 -  5328 * b3;

            /* mean the chroma for subsampling */

            u  = (u0+u1+u2+u3)>>2;
            v  = (v0+v1+v2+v3)>>2;

            y0 = (y0 * 219)/255 + 1048576;
            y1 = (y1 * 219)/255 + 1048576;
            y2 = (y2 * 219)/255 + 1048576;
            y3 = (y3 * 219)/255 + 1048576;

            u  = (u * 224)/255 ;
            v  = (v * 224)/255 ;

            *y1ptr++  = (y0 >> 16) ;
            *y1ptr++  = (y1 >> 16) ;
            *y2ptr++  = (y2 >> 16) ;
            *y2ptr++  = (y3 >> 16) ;


            *uptr++   = (u >> 16)+128 ;
            *vptr++   = (v >> 16)+128 ;

        }
        fwrite(y1buf, (cols & ~1), 1, yf);
        fwrite(y2buf, (cols & ~1), 1, yf);
        fwrite(ubuf, cols/2, 1, uf);
        fwrite(vbuf, cols/2, 1, vf);
    }

    pm_close(ifP);
    fclose(yf);
    fclose(uf);
    fclose(vf);
    return 0;
}