/* pbmtosunicon.c - read a PBM image and produce a Sun icon file ** ** Copyright (C) 1988 by Jef Poskanzer. ** ** Permission to use, copy, modify, and distribute this software and its ** documentation for any purpose and without fee is hereby granted, provided ** that the above copyright notice appear in all copies and that both that ** copyright notice and this permission notice appear in supporting ** documentation. This software is provided "as is" without express or ** implied warranty. */ /* 2006.10 (afu) Changed bitrow from plain to raw, read function from pbm_readpbmrow() to pbm_readpbmrow_packed. Applied wordint to scoop up 16 bit output items. putitem changed to better express the output format. Retired bitwise transformation functions. */ #include "pm_config.h" #include "pbm.h" static struct ItemPutter { unsigned short int itemBuff[8]; unsigned int itemCnt; /* takes values 0 to 8 */ FILE * putFp; } ip; static void putinit(FILE * const ofP) { ip.putFp = ofP; ip.itemCnt = 0; } static void putitem(uint16_t const item) { if (ip.itemCnt == 8 ) { /* Buffer is full. Write out one line. */ int rc; rc = fprintf(ip.putFp, "\t0x%04x,0x%04x,0x%04x,0x%04x," "0x%04x,0x%04x,0x%04x,0x%04x,\n", ip.itemBuff[0], ip.itemBuff[1], ip.itemBuff[2], ip.itemBuff[3], ip.itemBuff[4], ip.itemBuff[5], ip.itemBuff[6], ip.itemBuff[7]); if (rc < 0) pm_error("fprintf() failed to write Icon bitmap"); ip.itemCnt = 0; } ip.itemBuff[ip.itemCnt++] = item & 0xffff; /* Only lower 16 bits are used */ } static void putterm(void) { unsigned int i; for (i = 0; i < ip.itemCnt; ++i) { int rc; rc = fprintf(ip.putFp, "%s0x%04x%c", i == 0 ? "\t" : "", ip.itemBuff[i], i == ip.itemCnt - 1 ? '\n' : ','); if (rc < 0) pm_error("fprintf() failed to write Icon bitmap"); } } static void writeIconHeader(FILE * const ofP, unsigned int const width, unsigned int const height) { int rc; rc = fprintf(ofP, "/* Format_version=1, Width=%u, Height=%u", width, height); if (rc < 0) pm_error("fprintf() failed to write Icon header"); rc = fprintf(ofP, ", Depth=1, Valid_bits_per_item=16\n */\n"); if (rc < 0) pm_error("fprintf() failed to write Icon header"); } static void writeIcon(FILE * const ifP, unsigned int const cols, unsigned int const rows, int const format, FILE * const ofP) { unsigned int const items = (cols + 15) / 16; unsigned int const pad = items * 16 - cols; unsigned char * const bitrow = pbm_allocrow_packed(items * 16); unsigned int row; bitrow[0] = bitrow[items * 2 - 1] = 0; writeIconHeader(ofP, cols + pad, rows); putinit(ofP); for (row = 0; row < rows; ++row) { unsigned int itemSeq; pbm_readpbmrow_bitoffset(ifP, bitrow, cols, format, pad/2); for (itemSeq = 0; itemSeq < items; ++itemSeq) { /* Read bits from bitrow, send to format & print function. */ putitem((bitrow[itemSeq*2]<<8) + bitrow[itemSeq*2+1]); } } putterm(); pbm_freerow_packed(bitrow); } int main(int argc, char * argv[]) { FILE * ifP; int rows, cols; int format; const char * inputFileName; pbm_init(&argc, argv); if (argc-1 > 1) pm_error("Too many arguments (%u). " "Only argument is optional input file", argc-1); if (argc-1 == 1) inputFileName = argv[1]; else inputFileName = "-"; ifP = pm_openr(inputFileName); pbm_readpbminit(ifP, &cols, &rows, &format); writeIcon(ifP, cols, rows, format, stdout); pm_close(ifP); return 0; }