Blame converter/other/pamtoavs.c

Packit 78deda
/* ----------------------------------------------------------------------
Packit 78deda
 *
Packit 78deda
 * Convert a PAM image to an AVS X image
Packit 78deda
 *
Packit 78deda
 * By Scott Pakin <scott+pbm@pakin.org>
Packit 78deda
 *
Packit 78deda
 * ----------------------------------------------------------------------
Packit 78deda
 *
Packit 78deda
 * Copyright (C) 2010 Scott Pakin <scott+pbm@pakin.org>
Packit 78deda
 *
Packit 78deda
 * This program is free software: you can redistribute it and/or modify
Packit 78deda
 * it under the terms of the GNU General Public License as published by
Packit 78deda
 * the Free Software Foundation, either version 3 of the License, or (at
Packit 78deda
 * your option) any later version.
Packit 78deda
 *
Packit 78deda
 * This program is distributed in the hope that it will be useful, but
Packit 78deda
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 78deda
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 78deda
 * General Public License for more details.
Packit 78deda
 *
Packit 78deda
 * You should have received a copy of the GNU General Public License
Packit 78deda
 * along with this program.  If not, see http://www.gnu.org/licenses/.
Packit 78deda
 *
Packit 78deda
 * ----------------------------------------------------------------------
Packit 78deda
 */
Packit 78deda
Packit 78deda
#include <stdio.h>
Packit 78deda
#include "pm.h"
Packit 78deda
#include "pam.h"
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
static char
Packit 78deda
sample2char(sample const s,
Packit 78deda
            sample const maxval) {
Packit 78deda
/* Scale down a sample to a single byte. */
Packit 78deda
Packit 78deda
    return maxval==255 ? s : s * 255 / maxval;
Packit 78deda
}
Packit 78deda
Packit 78deda
Packit 78deda
#define THIS_SAMPLE_CHAR(PLANE) \
Packit 78deda
  sample2char(tuplerow[col][PLANE], pamP->maxval)
Packit 78deda
Packit 78deda
static void
Packit 78deda
produceAvs(struct pam * const pamP,
Packit 78deda
           FILE *       const avsFileP) {
Packit 78deda
Packit 78deda
    tuple * tuplerow;
Packit 78deda
Packit 78deda
    /* Write the AVS header (image width and height as 4-byte
Packit 78deda
       big-endian integers).
Packit 78deda
    */
Packit 78deda
    pm_writebiglong(avsFileP, pamP->width);
Packit 78deda
    pm_writebiglong(avsFileP, pamP->height);
Packit 78deda
Packit 78deda
    /* Write the AVS data (alpha, red, green, blue -- one byte apiece. */
Packit 78deda
    tuplerow = pnm_allocpamrow(pamP);
Packit 78deda
    switch (pamP->depth) {
Packit 78deda
    case 1: {
Packit 78deda
        /* Black-and-white or grayscale, no alpha */
Packit 78deda
        unsigned int row;
Packit 78deda
        for (row = 0; row < pamP->height; ++row) {
Packit 78deda
            unsigned int col;
Packit 78deda
            pnm_readpamrow(pamP, tuplerow);
Packit 78deda
            for (col = 0; col < pamP->width; ++col) {
Packit 78deda
                pm_writechar(avsFileP, (char)255);
Packit 78deda
                pm_writechar(avsFileP, THIS_SAMPLE_CHAR(0));
Packit 78deda
                pm_writechar(avsFileP, THIS_SAMPLE_CHAR(0));
Packit 78deda
                pm_writechar(avsFileP, THIS_SAMPLE_CHAR(0));
Packit 78deda
            }
Packit 78deda
        }
Packit 78deda
    } break;
Packit 78deda
Packit 78deda
    case 2: {
Packit 78deda
        /* Black-and-white or grayscale plus alpha */
Packit 78deda
        unsigned int row;
Packit 78deda
        for (row = 0; row < pamP->height; ++row) {
Packit 78deda
            unsigned int col;
Packit 78deda
            pnm_readpamrow(pamP, tuplerow);
Packit 78deda
            for (col = 0; col < pamP->width; ++col) {
Packit 78deda
                pm_writechar(avsFileP, THIS_SAMPLE_CHAR(1));
Packit 78deda
                pm_writechar(avsFileP, THIS_SAMPLE_CHAR(0));
Packit 78deda
                pm_writechar(avsFileP, THIS_SAMPLE_CHAR(0));
Packit 78deda
                pm_writechar(avsFileP, THIS_SAMPLE_CHAR(0));
Packit 78deda
            }
Packit 78deda
        }
Packit 78deda
    } break;
Packit 78deda
Packit 78deda
    case 3: {
Packit 78deda
        /* RGB, no alpha */
Packit 78deda
        unsigned int row;
Packit 78deda
        for (row = 0; row < pamP->height; ++row) {
Packit 78deda
            unsigned int col;
Packit 78deda
            pnm_readpamrow(pamP, tuplerow);
Packit 78deda
            for (col = 0; col < pamP->width; ++col) {
Packit 78deda
                pm_writechar(avsFileP, (char)255);
Packit 78deda
                pm_writechar(avsFileP, THIS_SAMPLE_CHAR(0));
Packit 78deda
                pm_writechar(avsFileP, THIS_SAMPLE_CHAR(1));
Packit 78deda
                pm_writechar(avsFileP, THIS_SAMPLE_CHAR(2));
Packit 78deda
            }
Packit 78deda
        }
Packit 78deda
    } break;
Packit 78deda
Packit 78deda
    case 4: {
Packit 78deda
        /* RGB plus alpha */
Packit 78deda
        unsigned int row;
Packit 78deda
        for (row = 0; row < pamP->height; ++row) {
Packit 78deda
            unsigned int col;
Packit 78deda
            pnm_readpamrow( pamP, tuplerow );
Packit 78deda
            for (col = 0; col < pamP->width; ++col) {
Packit 78deda
                pm_writechar(avsFileP, THIS_SAMPLE_CHAR(3));
Packit 78deda
                pm_writechar(avsFileP, THIS_SAMPLE_CHAR(0));
Packit 78deda
                pm_writechar(avsFileP, THIS_SAMPLE_CHAR(1));
Packit 78deda
                pm_writechar(avsFileP, THIS_SAMPLE_CHAR(2));
Packit 78deda
            }
Packit 78deda
        }
Packit 78deda
    } break;
Packit 78deda
Packit 78deda
    default:
Packit 78deda
        pm_error("Unrecognized PAM depth %u.  We understand only "
Packit 78deda
                 "1, 2, 3, and 4", pamP->depth);
Packit 78deda
        break;
Packit 78deda
    }
Packit 78deda
    pnm_freepamrow(tuplerow);
Packit 78deda
}
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
int
Packit 78deda
main(int argc, const char *argv[]) {
Packit 78deda
    struct pam   inPam;
Packit 78deda
    const char * inputFilename;
Packit 78deda
    FILE       * inFileP;
Packit 78deda
Packit 78deda
    pm_proginit(&argc, argv);
Packit 78deda
Packit 78deda
    inputFilename = (argc > 1) ? argv[1] : "-";
Packit 78deda
Packit 78deda
    inFileP = pm_openr(inputFilename);
Packit 78deda
Packit 78deda
    pnm_readpaminit(inFileP, &inPam, PAM_STRUCT_SIZE(tuple_type));
Packit 78deda
Packit 78deda
    produceAvs(&inPam, stdout);
Packit 78deda
Packit 78deda
    pm_closer(inFileP);
Packit 78deda
Packit 78deda
    return 0;
Packit 78deda
}
Packit 78deda