diff options
Diffstat (limited to 'converter/other')
-rw-r--r-- | converter/other/ipdb.c | 222 | ||||
-rw-r--r-- | converter/other/ipdb.h | 23 | ||||
-rw-r--r-- | converter/other/pamtopdbimg.c | 76 | ||||
-rw-r--r-- | converter/other/pamtoxvmini.c | 77 | ||||
-rw-r--r-- | converter/other/pdbimgtopam.c | 127 | ||||
-rw-r--r-- | converter/other/pnmtorle.c | 276 | ||||
-rw-r--r-- | converter/other/pnmtosir.c | 35 |
7 files changed, 482 insertions, 354 deletions
diff --git a/converter/other/ipdb.c b/converter/other/ipdb.c index 5e4dc82e..d524c7e9 100644 --- a/converter/other/ipdb.c +++ b/converter/other/ipdb.c @@ -23,15 +23,12 @@ #define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */ #define _BSD_SOURCE /* Ensure strdup() is in <string.h> */ #include <assert.h> -#include <time.h> #include <string.h> #include "mallocvar.h" #include "nstring.h" -#include "ipdb.h" - -typedef uint32_t pilot_time_t; +#include "ipdb.h" @@ -49,7 +46,7 @@ imgPpb(IMAGE * const imgP) { unsigned int -ipdb_img_ppb(IMAGE * const imgP) { +ipdb_imgPpb(IMAGE * const imgP) { /*---------------------------------------------------------------------------- Pixels per byte -----------------------------------------------------------------------------*/ @@ -59,7 +56,7 @@ ipdb_img_ppb(IMAGE * const imgP) { size_t -ipdb_img_size(IMAGE * const imgP) { +ipdb_imgSize(IMAGE * const imgP) { /*---------------------------------------------------------------------------- Size (in bytes) of an image's data. -----------------------------------------------------------------------------*/ @@ -71,115 +68,97 @@ ipdb_img_size(IMAGE * const imgP) { /* * Return the start of row `r'. */ - uint8_t * - ipdb_img_row(IMAGE * const imgP, - unsigned int const row) { - - return &imgP->data[(row) * imgP->width / imgPpb(imgP)]; - } - - +uint8_t * +ipdb_imgRow(IMAGE * const imgP, + unsigned int const row) { - #define img_row(i, r) - - static pilot_time_t const unixepoch = (66*365+17)*24*3600; - /* The unix epoch in Mac time (the Mac epoch is 00:00 UTC 1904.01.01). - The 17 is the number of leap years. - */ - - static const char * const errorDesc[] = { - /* E_BADCOLORS */ - "Invalid palette, only {0x00, 0x55, 0xAA, 0xFF} allowed.", + return &imgP->data[(row) * imgP->width / imgPpb(imgP)]; +} - /* E_NOTIMAGE */ - "Not an image file.", - /* E_IMAGETHERE */ - "Image record already present, logic error.", - /* E_IMAGENOTTHERE */ - "Image record required before text record, logic error.", +static const char * const errorDesc[] = { + /* E_BADCOLORS */ + "Invalid palette, only {0x00, 0x55, 0xAA, 0xFF} allowed.", - /* E_TEXTTHERE */ - "Text record already present, logic error.", + /* E_NOTIMAGE */ + "Not an image file.", - /* E_NOTRECHDR */ - "Invalid record header encountered.", + /* E_IMAGETHERE */ + "Image record already present, logic error.", - /* E_UNKNOWNRECHDR */ - "Unknown record header.", + /* E_IMAGENOTTHERE */ + "Image record required before text record, logic error.", - /* E_TOOBIGG */ - "Image too big, maximum size approx. 640*400 gray pixels.", + /* E_TEXTTHERE */ + "Text record already present, logic error.", - /* E_TOOBIGM */ - "Image too big, maximum size approx. 640*800 monochrome pixels.", - }; + /* E_NOTRECHDR */ + "Invalid record header encountered.", + /* E_UNKNOWNRECHDR */ + "Unknown record header.", + /* E_TOOBIGG */ + "Image too big, maximum size approx. 640*400 gray pixels.", - const char * - ipdb_err(int const e) { + /* E_TOOBIGM */ + "Image too big, maximum size approx. 640*800 monochrome pixels.", +}; - if (e < 0) - return e >= E_LAST ? errorDesc[-e - 1] : "unknown error"; - else - return strerror(e); - } +const char * +ipdb_err(int const e) { - static void - rechdr_free(RECHDR * const recP) { + if (e < 0) + return e >= E_LAST ? errorDesc[-e - 1] : "unknown error"; + else + return strerror(e); +} - if (recP) { - free(recP->extra); - free(recP); - } - } +static void +rechdr_free(RECHDR * const recP) { - void - ipdb_image_free(IMAGE * const imgP) { + if (recP) { + free(recP->extra); + free(recP); + } +} - if (imgP) { - rechdr_free(imgP->r); - free(imgP->data); - free(imgP); - } - } +void +ipdb_imageFree(IMAGE * const imgP) { - void - ipdb_text_free(TEXT * const textP) { + if (imgP) { + rechdr_free(imgP->r); + free(imgP->data); + free(imgP); + } +} - if (textP) { - rechdr_free(textP->r); - free(textP->data); - free(textP); - } - } +void +ipdb_textFree(TEXT * const textP) { - void - ipdb_pdbhead_free(PDBHEAD * const headP) { + if (textP) { + rechdr_free(textP->r); + if (textP->data) + free(textP->data); + free(textP); + } +} - free(headP); - } +void +ipdb_pdbheadFree(PDBHEAD * const headP) { - void - ipdb_clear(IPDB * const pdbP) { - - if (pdbP) { - ipdb_image_free(pdbP->i); - ipdb_text_free(pdbP->t); - ipdb_pdbhead_free(pdbP->p); - } + free(headP); } @@ -187,14 +166,22 @@ ipdb_img_size(IMAGE * const imgP) { void ipdb_free(IPDB * const pdbP) { - ipdb_clear(pdbP); + if (pdbP->i) + ipdb_imageFree(pdbP->i); + + if (pdbP->t) + ipdb_textFree(pdbP->t); + + if (pdbP->p) + ipdb_pdbheadFree(pdbP->p); + free(pdbP); } PDBHEAD * -ipdb_pdbhead_alloc(const char * const name) { +ipdb_pdbheadAlloc() { PDBHEAD * pdbHeadP; @@ -202,20 +189,6 @@ ipdb_pdbhead_alloc(const char * const name) { if (pdbHeadP) { MEMSZERO(pdbHeadP); - - STRSCPY(pdbHeadP->name, name == NULL ? "unnamed" : name); - - /* - * All of the Image Viewer pdb files that I've come across have - * 3510939142U (1997.08.16 14:38:22 UTC) here. I don't know where - * this bizarre date comes from but the real date works fine so - * I'm using it. - */ - pdbHeadP->ctime = - pdbHeadP->mtime = (pilot_time_t)time(NULL) + unixepoch; - - MEMSCPY(&pdbHeadP->type, IPDB_vIMG); - MEMSCPY(&pdbHeadP->id, IPDB_View); } return pdbHeadP; } @@ -223,7 +196,7 @@ ipdb_pdbhead_alloc(const char * const name) { static RECHDR * -rechdr_alloc(int const type, +rechdrCreate(int const type, uint32_t const offset) { /* @@ -234,7 +207,7 @@ rechdr_alloc(int const type, RECHDR * recHdrP; MALLOCVAR(recHdrP); - + if (recHdrP) { MEMSSET(recHdrP, 0); @@ -255,10 +228,10 @@ rechdr_alloc(int const type, IMAGE * -ipdb_image_alloc(const char * const name, - int const type, - int const w, - int const h) { +ipdb_imageCreate(const char * const name, + int const type, + int const w, + int const h) { bool failed; IMAGE * imgP; @@ -277,7 +250,7 @@ ipdb_image_alloc(const char * const name, imgP->width = w; imgP->height = h; - imgP->r = rechdr_alloc(IMG_REC, IMGOFFSET); + imgP->r = rechdrCreate(IMG_REC, IMGOFFSET); if (imgP->r) { if (w != 0 && h != 0) { @@ -292,10 +265,10 @@ ipdb_image_alloc(const char * const name, rechdr_free(imgP->r); } else failed = true; - + if (failed) - ipdb_image_free(imgP); - } else + ipdb_imageFree(imgP); + } else failed = true; return failed ? NULL : imgP; @@ -304,7 +277,7 @@ ipdb_image_alloc(const char * const name, TEXT * -ipdb_text_alloc(const char * const content) { +ipdb_textAlloc(void) { TEXT * textP; bool failed; @@ -320,22 +293,13 @@ ipdb_text_alloc(const char * const content) { if (textP) { MEMSZERO(textP); - textP->r = rechdr_alloc(TEXT_REC, 0); + textP->r = rechdrCreate(TEXT_REC, 0); - if (textP->r) { - if (content) { - textP->data = strdup(content); - - if (!textP->data) - failed = true; - } - if (failed) - rechdr_free(textP->r); - } else + if (textP->r == NULL) failed = true; if (failed) - ipdb_text_free(textP); + free(textP); } else failed = true; @@ -345,7 +309,7 @@ ipdb_text_alloc(const char * const content) { IPDB * -ipdb_alloc(const char * const name) { +ipdb_alloc(void) { IPDB * pdbP; bool failed; @@ -357,12 +321,11 @@ ipdb_alloc(const char * const name) { if (pdbP) { MEMSZERO(pdbP); - if (name) { - pdbP->p = ipdb_pdbhead_alloc(name); + pdbP->p = ipdb_pdbheadAlloc(); + + if (!pdbP->p) + failed = true; - if (!pdbP->p) - failed = true; - } if (failed) ipdb_free(pdbP); } else @@ -383,3 +346,6 @@ ipdb_typeName(uint8_t const type) { default: return "???"; } } + + + diff --git a/converter/other/ipdb.h b/converter/other/ipdb.h index 6af5fc44..59e5d266 100644 --- a/converter/other/ipdb.h +++ b/converter/other/ipdb.h @@ -201,43 +201,40 @@ const char * ipdb_err(int error); size_t -ipdb_img_size(IMAGE * const imgP); +ipdb_imgSize(IMAGE * const imgP); unsigned int -ipdb_img_ppb(IMAGE * const imgP); +ipdb_imgPpb(IMAGE * const imgP); uint8_t * -ipdb_img_row(IMAGE * const imgP, +ipdb_imgRow(IMAGE * const imgP, unsigned int const row); void ipdb_free(IPDB *); IPDB * -ipdb_alloc(const char *); - -void -ipdb_clear(IPDB * const pdbP); +ipdb_alloc(void); PDBHEAD * -ipdb_pdbhead_alloc(const char * const name); +ipdb_pdbheadAlloc(void); void -ipdb_pdbhead_free(PDBHEAD * const headP); +ipdb_pdbheadFree(PDBHEAD * const headP); IMAGE * -ipdb_image_alloc(const char * const name, +ipdb_imageCreate(const char * const name, int const type, int const w, int const h); void -ipdb_image_free(IMAGE * const imgP); +ipdb_imageFree(IMAGE * const imgP); void -ipdb_text_free(TEXT * const textP); +ipdb_textFree(TEXT * const textP); TEXT * -ipdb_text_alloc(const char * const content); +ipdb_textAlloc(void); #endif diff --git a/converter/other/pamtopdbimg.c b/converter/other/pamtopdbimg.c index 4823686f..da0f5064 100644 --- a/converter/other/pamtopdbimg.c +++ b/converter/other/pamtopdbimg.c @@ -32,6 +32,7 @@ #include <stdlib.h> #include <assert.h> #include <string.h> +#include <time.h> #include <sys/stat.h> #include "pm_c_util.h" @@ -45,7 +46,7 @@ enum CompMode {COMPRESSED, MAYBE, UNCOMPRESSED}; -struct cmdlineInfo { +struct CmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ @@ -54,13 +55,14 @@ struct cmdlineInfo { const char * notefile; /* NULL if not specified */ enum CompMode compMode; unsigned int depth4; + unsigned int fixedtime; }; static void parseCommandLine(int argc, const char ** argv, - struct cmdlineInfo * const cmdlineP) { + struct CmdlineInfo * const cmdlineP) { /*---------------------------------------------------------------------------- parse program command line described in Unix standard form by argc and argv. Return the information in the options as *cmdlineP. @@ -96,6 +98,8 @@ parseCommandLine(int argc, const char ** argv, &uncompressed, 0); OPTENT3(0, "4depth", OPT_FLAG, NULL, &cmdlineP->depth4, 0); + OPTENT3(0, "fixedtime", OPT_FLAG, NULL, + &cmdlineP->fixedtime, 0); opt.opt_table = option_def; opt.short_allowed = false; /* We have no short (old-fashioned) options */ @@ -144,6 +148,42 @@ parseCommandLine(int argc, const char ** argv, +static uint32_t const unixepoch = (66*365+17)*24*3600; + /* The unix epoch in Mac time (the Mac epoch is 00:00 UTC 1904.01.01). + The 17 is the number of leap years. + */ + + + +static void +setPdbHeader(PDBHEAD * const pdbHeadP, + const char * const name, + bool const wantFixedTime) { + + STRSCPY(pdbHeadP->name, name); + + { + /* + * All of the Image Viewer pdb files that I've come across have + * 3510939142U (1997.08.16 14:38:22 UTC) here. I don't know where + * this bizarre datetime comes from but the real date works fine so + * I'm using it unless user asked for a fixed time (probably just so he + * gets repeatable output). + */ + + uint32_t const stdTime = 3510939142U; + + uint32_t const hdrDt = + wantFixedTime ? stdTime : (uint32_t)time(NULL) + unixepoch; + + pdbHeadP->ctime = pdbHeadP->mtime = hdrDt; + } + MEMSCPY(&pdbHeadP->type, IPDB_vIMG); + MEMSCPY(&pdbHeadP->id, IPDB_View); +} + + + static int pdbheadWrite(PDBHEAD * const pdbheadP, FILE * const fileP) { @@ -249,9 +289,9 @@ compressIfRequired(IPDB * const pdbP, if (comp == IPDB_NOCOMPRESS) { *compressedDataP = pdbP->i->data; - *compressedSizeP = ipdb_img_size(pdbP->i); + *compressedSizeP = ipdb_imgSize(pdbP->i); } else { - int const uncompressedSz = ipdb_img_size(pdbP->i); + int const uncompressedSz = ipdb_imgSize(pdbP->i); unsigned char * outbuf; size_t compressedSz; @@ -475,7 +515,7 @@ imageInsertInit(IPDB * const pdbP, ipdb_typeName(type), MAX_SIZE(type)); else { pdbP->i = - ipdb_image_alloc(name, type, adjustedWidth, adjustedHeight); + ipdb_imageCreate(name, type, adjustedWidth, adjustedHeight); if (pdbP->i == NULL) pm_message("Could not get memory for %u x %u image", adjustedWidth, adjustedHeight); @@ -582,7 +622,7 @@ insertMimage(IPDB * const pdbP, static int insertText(IPDB * const pdbP, - const char * const s) { + const char * const content) { int retval; @@ -591,17 +631,23 @@ insertText(IPDB * const pdbP, else if (pdbP->p->num_recs == 2) retval = E_TEXTTHERE; else { - pdbP->t = ipdb_text_alloc(s); + pdbP->t = ipdb_textAlloc(); if (pdbP->t == NULL) retval = ENOMEM; else { - pdbP->p->num_recs = 2; + pdbP->t->data = strdup(content); - pdbP->i->r->offset += 8; - pdbP->t->r->offset = - pdbP->i->r->offset + IMAGESIZE + ipdb_img_size(pdbP->i); + if (pdbP->t->data == NULL) + retval = ENOMEM; + else { + pdbP->p->num_recs = 2; - retval = 0; + pdbP->i->r->offset += 8; + pdbP->t->r->offset = + pdbP->i->r->offset + IMAGESIZE + ipdb_imgSize(pdbP->i); + + retval = 0; + } } } return retval; @@ -689,7 +735,7 @@ readtxt(IPDB * const pdbP, int main(int argc, const char **argv) { - struct cmdlineInfo cmdline; + struct CmdlineInfo cmdline; IPDB * pdbP; FILE * ifP; int comp; @@ -709,11 +755,13 @@ main(int argc, const char **argv) { if (strlen(cmdline.title) > 31) pm_error("Title too long. Max length is 31 characters."); - pdbP = ipdb_alloc(cmdline.title); + pdbP = ipdb_alloc(); if (pdbP == NULL) pm_error("Failed to allocate IPDB structure"); + setPdbHeader(pdbP->p, cmdline.title, cmdline.fixedtime); + readimg(pdbP, ifP, cmdline.depth4); if (cmdline.notefile) diff --git a/converter/other/pamtoxvmini.c b/converter/other/pamtoxvmini.c index b57bcc74..047de75a 100644 --- a/converter/other/pamtoxvmini.c +++ b/converter/other/pamtoxvmini.c @@ -23,16 +23,16 @@ typedef struct xvPalette { } xvPalette; -struct cmdlineInfo { +struct CmdlineInfo { const char * inputFileName; }; static void -parseCommandLine(int const argc, - char * argv[], - struct cmdlineInfo * const cmdlineP) { +parseCommandLine(int const argc, + const char * argv[], + struct CmdlineInfo * const cmdlineP) { if (argc-1 < 1) cmdlineP->inputFileName = "-"; @@ -75,7 +75,7 @@ static void writeXvHeader(FILE * const ofP, unsigned int const cols, unsigned int const rows) { - + fprintf(ofP, "P7 332\n"); fprintf(ofP, "# Created by Pamtoxvmini\n"); @@ -94,12 +94,14 @@ writeXvHeader(FILE * const ofP, static void findClosestColor(struct pam * const pamP, - tuple const tuple, + tuple const tuple, const xvPalette * const xvPaletteP, unsigned int * const paletteIndexP) { /*---------------------------------------------------------------------------- Find the color in the palette *xvPaletteP that is closest to the color 'tuple' and return its index in the palette. + + *pamP gives the format of 'tuple', which must be RGB with maxval 255. -----------------------------------------------------------------------------*/ unsigned int paletteIndex; unsigned int bestPaletteIndex; @@ -118,12 +120,12 @@ findClosestColor(struct pam * const pamP, unsigned int const tupleRed = tuple[PAM_RED_PLANE]; unsigned int const tupleGrn = tuple[PAM_GRN_PLANE]; unsigned int const tupleBlu = tuple[PAM_BLU_PLANE]; - + unsigned int const paletteRed = xvPaletteP->red[paletteIndex]; unsigned int const paletteGrn = xvPaletteP->grn[paletteIndex]; unsigned int const paletteBlu = xvPaletteP->blu[paletteIndex]; - unsigned int const distance = + unsigned int const distance = SQR((int)tupleRed - (int)paletteRed) + SQR((int)tupleGrn - (int)paletteGrn) + SQR((int)tupleBlu - (int)paletteBlu); @@ -155,24 +157,29 @@ getPaletteIndexThroughCache(struct pam * const pamP, int found; int paletteIndex; + /* As required by findClosestColor(): */ + assert(pamP->depth >= 3); + assert(pamP->maxval == 255); + pnm_lookuptuple(pamP, paletteHash, tuple, &found, &paletteIndex); if (found) *paletteIndexP = paletteIndex; else { int fits; + findClosestColor(pamP, tuple, xvPaletteP, paletteIndexP); - + pnm_addtotuplehash(pamP, paletteHash, tuple, *paletteIndexP, &fits); - + if (!fits) pm_error("Can't get memory for palette hash."); } } - + static void -writeXvRaster(struct pam * const pamP, +writeXvRaster(struct pam * const inpamP, xvPalette * const xvPaletteP, FILE * const ofP) { /*---------------------------------------------------------------------------- @@ -190,33 +197,40 @@ writeXvRaster(struct pam * const pamP, unsigned int row; unsigned char * xvrow; struct pam scaledPam; + struct pam scaledRgbPam; + + pnm_setminallocationdepth(inpamP, 3); paletteHash = pnm_createtuplehash(); - tuplerow = pnm_allocpamrow(pamP); - xvrow = (unsigned char*)pm_allocrow(pamP->width, 1); + tuplerow = pnm_allocpamrow(inpamP); + xvrow = (unsigned char*)pm_allocrow(inpamP->width, 1); - scaledPam = *pamP; + scaledPam = *inpamP; /* initial value */ scaledPam.maxval = 255; - for (row = 0; row < pamP->height; ++row) { + scaledRgbPam = scaledPam; /* initial value */ + scaledRgbPam.depth = MAX(3, scaledPam.depth); + + for (row = 0; row < inpamP->height; ++row) { unsigned int col; - pnm_readpamrow(pamP, tuplerow); - pnm_scaletuplerow(pamP, tuplerow, tuplerow, scaledPam.maxval); + pnm_readpamrow(inpamP, tuplerow); + pnm_scaletuplerow(inpamP, tuplerow, tuplerow, scaledPam.maxval); pnm_makerowrgb(&scaledPam, tuplerow); - for (col = 0; col < scaledPam.width; ++col) { + for (col = 0; col < scaledRgbPam.width; ++col) { unsigned int paletteIndex; - getPaletteIndexThroughCache(&scaledPam, tuplerow[col], xvPaletteP, - paletteHash, &paletteIndex); + getPaletteIndexThroughCache(&scaledRgbPam, tuplerow[col], + xvPaletteP, paletteHash, + &paletteIndex); assert(paletteIndex < 256); xvrow[col] = paletteIndex; } - fwrite(xvrow, 1, scaledPam.width, ofP); + fwrite(xvrow, 1, scaledRgbPam.width, ofP); } pm_freerow((char*)xvrow); @@ -227,16 +241,16 @@ writeXvRaster(struct pam * const pamP, -int -main(int argc, - char * argv[]) { +int +main(int argc, + const char * argv[]) { - struct cmdlineInfo cmdline; + struct CmdlineInfo cmdline; FILE * ifP; struct pam pam; xvPalette xvPalette; - - pnm_init(&argc, argv); + + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); @@ -246,13 +260,14 @@ main(int argc, pnm_readpaminit(ifP, &pam, PAM_STRUCT_SIZE(allocation_depth)); - pnm_setminallocationdepth(&pam, 3); - writeXvHeader(stdout, pam.width, pam.height); - + writeXvRaster(&pam, &xvPalette, stdout); pm_close(ifP); return 0; } + + + diff --git a/converter/other/pdbimgtopam.c b/converter/other/pdbimgtopam.c index 67044109..b191644f 100644 --- a/converter/other/pdbimgtopam.c +++ b/converter/other/pdbimgtopam.c @@ -56,7 +56,7 @@ parseCommandLine(int argc, const char ** argv, struct cmdlineInfo * const cmdlineP) { /*---------------------------------------------------------------------------- parse program command line described in Unix standard form by argc - and argv. Return the information in the options as *cmdlineP. + and argv. Return the information in the options as *cmdlineP. If command line is internally inconsistent (invalid options, etc.), issue error message to stderr and abort program. @@ -90,7 +90,7 @@ parseCommandLine(int argc, const char ** argv, if (!notefileSpec) cmdlineP->notefile = NULL; - + if (argc-1 < 1) cmdlineP->inputFileName = "-"; else if (argc-1 == 1) @@ -152,7 +152,7 @@ decompress(const uint8_t * const compressed, const uint8_t * inP; uint8_t * outP; size_t bytesLeft; - + for (bytesLeft = imageSize, inP = &compressed[0], outP = &uncompressed[0]; bytesLeft > 0; @@ -224,7 +224,7 @@ readCompressed(IMAGE * const imgP, * this extra byte and ignore it by paying attention to * the image dimensions. */ - size_t const maxCompressedSizeWithBloat = ipdb_img_size(imgP) * 2; + size_t const maxCompressedSizeWithBloat = ipdb_imgSize(imgP) * 2; /* * Provide a buffer large enough for the worst case. * See note in lib/util/runlength.c . @@ -251,7 +251,7 @@ readCompressed(IMAGE * const imgP, * Read to the indicated offset. */ dataSize = end_offset - ftell(fP) + 1; - + MALLOCARRAY(buffer, dataSize); if (buffer == NULL) @@ -306,9 +306,9 @@ imageReadHeader(FILE * const fileP, pm_message(" Y_anchor: %u", imgP->y_anchor); pm_message(" Width: %u", imgP->width); pm_message(" Height: %u", imgP->height); - pm_message("Pixels per byte: %u", ipdb_img_ppb(imgP)); + pm_message("Pixels per byte: %u", ipdb_imgPpb(imgP)); pm_message("Image size: %lu bytes", - (unsigned long)ipdb_img_size(imgP)); + (unsigned long)ipdb_imgSize(imgP)); } } @@ -318,7 +318,7 @@ imageReadData(FILE * const fileP, IMAGE * const imgP, uint32_t const end_offset) { - size_t const imageSize = ipdb_img_size(imgP); + size_t const imageSize = ipdb_imgSize(imgP); int retval; size_t dataSize; @@ -390,7 +390,7 @@ textRead(TEXT * const textP, return 0; textP->r->offset = (uint32_t)ftell(fileP); - + /* * What a pain in the ass! Why the hell isn't there a length * attached to the text record? I suppose the designer wasn't @@ -453,7 +453,7 @@ pdbheadRead(PDBHEAD * const pdbHeadP, pm_readbiglongu2(fileP, &pdbHeadP->next_rec); pm_readbigshortu(fileP, &pdbHeadP->num_recs); - if (!memeq(pdbHeadP->type, IPDB_vIMG, 4) + if (!memeq(pdbHeadP->type, IPDB_vIMG, 4) || !memeq(pdbHeadP->id, IPDB_View, 4)) retval = E_NOTIMAGE; else @@ -531,62 +531,54 @@ ipdbRead(IPDB * const pdbP, int retval; - ipdb_clear(pdbP); + int status; - pdbP->p = ipdb_pdbhead_alloc(NULL); + status = pdbheadRead(pdbP->p, fileP); - if (pdbP->p == NULL) - retval = ENOMEM; + if (status != 0) + retval = status; else { - int status; - - status = pdbheadRead(pdbP->p, fileP); - - if (status != 0) - retval = status; + pdbP->i = ipdb_imageCreate(pdbP->p->name, IMG_GRAY, 0, 0); + if (pdbP->i == NULL) + retval = ENOMEM; else { - pdbP->i = ipdb_image_alloc(pdbP->p->name, IMG_GRAY, 0, 0); - if (pdbP->i == NULL) - retval = ENOMEM; + int status; + status = rechdrRead(pdbP->i->r, fileP); + if (status != 0) + retval = status; else { - int status; - status = rechdrRead(pdbP->i->r, fileP); - if (status != 0) - retval = status; - else { - if (pdbP->p->num_recs > 1) { - pdbP->t = ipdb_text_alloc(NULL); - if (pdbP->t == NULL) - retval = ENOMEM; - else { - int status; - status = rechdrRead(pdbP->t->r, fileP); - if (status != 0) - retval = status; - else - retval = 0; - } - } else - retval = 0; - - if (retval == 0) { - uint32_t const offset = - pdbP->t == NULL ? - UNKNOWN_OFFSET : pdbP->t->r->offset - 1; - + if (pdbP->p->num_recs > 1) { + pdbP->t = ipdb_textAlloc(); + if (pdbP->t == NULL) + retval = ENOMEM; + else { int status; - - status = imageRead(pdbP->i, offset, fileP, verbose); + status = rechdrRead(pdbP->t->r, fileP); if (status != 0) retval = status; - else { - if (pdbP->t != NULL) { - int status; - - status = textRead(pdbP->t, fileP); - if (status != 0) - retval = status; - } + else + retval = 0; + } + } else + retval = 0; + + if (retval == 0) { + uint32_t const offset = + pdbP->t == NULL ? + UNKNOWN_OFFSET : pdbP->t->r->offset - 1; + + int status; + + status = imageRead(pdbP->i, offset, fileP, verbose); + if (status != 0) + retval = status; + else { + if (pdbP->t != NULL) { + int status; + + status = textRead(pdbP->t, fileP); + if (status != 0) + retval = status; } } } @@ -663,8 +655,8 @@ static void g16row(IPDB * const pdbP, unsigned int const row, uint8_t * const buffer) { - - g16unpack(ipdb_img_row(pdbP->i, row), buffer, ipdb_width(pdbP)); + + g16unpack(ipdb_imgRow(pdbP->i, row), buffer, ipdb_width(pdbP)); } @@ -674,7 +666,7 @@ grow(IPDB * const pdbP, unsigned int const row, uint8_t * const buffer) { - gunpack(ipdb_img_row(pdbP->i, row), buffer, ipdb_width(pdbP)); + gunpack(ipdb_imgRow(pdbP->i, row), buffer, ipdb_width(pdbP)); } @@ -684,7 +676,7 @@ mrow(IPDB * const pdbP, unsigned int const row, uint8_t * const buffer) { - munpack(ipdb_img_row(pdbP->i, row), buffer, ipdb_width(pdbP)); + munpack(ipdb_imgRow(pdbP->i, row), buffer, ipdb_width(pdbP)); } @@ -715,7 +707,7 @@ writeImgPam(IPDB * const pdbP, PAM_PBM_TUPLETYPE : PAM_PGM_TUPLETYPE); pnm_writepaminit(&pam); - + tupleRow = pnm_allocpamrow(&pam); for (row = 0; row < pam.height; ++row) { @@ -731,7 +723,7 @@ writeImgPam(IPDB * const pdbP, for (col = 0; col < pam.width; ++col) tupleRow[col][0] = imgRow[col]; - + pnm_writepamrow(&pam, tupleRow); } pnm_freepamrow(tupleRow); @@ -754,7 +746,7 @@ writeText(IPDB * const pdbP, 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); @@ -777,7 +769,7 @@ main(int argc, const char ** argv) { ifP = pm_openr(cmdline.inputFileName); - pdbP = ipdb_alloc(NULL); + pdbP = ipdb_alloc(); if (pdbP == NULL) pm_error("Could not allocate IPDB structure."); @@ -795,3 +787,6 @@ main(int argc, const char ** argv) { return EXIT_SUCCESS; } + + + diff --git a/converter/other/pnmtorle.c b/converter/other/pnmtorle.c index d61884dd..17c9cfbc 100644 --- a/converter/other/pnmtorle.c +++ b/converter/other/pnmtorle.c @@ -33,71 +33,157 @@ * 2000.04.13 adapted for Netpbm by Bryan Henderson. Quieted compiler * warnings. * + * 2022.03.06 revision by Akira F Urushibata + * use shhopt instead of scanargs + * proper handling of multiple image files with -h + * */ /*----------------------------------------------------- * System includes. */ #include <string.h> #include <stdio.h> +#include <assert.h> #include "pnm.h" #include "mallocvar.h" #include "rle.h" +#include "shhopt.h" +#include "pm_c_util.h" + + +struct CmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char * inFileName; + const char * outfile; + unsigned int verbose; + unsigned int header; + unsigned int alpha; +}; + + + +static void +parseCommandLine(int argc, const char ** argv, + struct CmdlineInfo * const cmdlineP) { +/*---------------------------------------------------------------------------- + Note that the file spec array we return is stored in the storage that + was passed to us as the argv array. +-----------------------------------------------------------------------------*/ + optEntry * option_def; + /* Instructions to pm_optParseOptions3 on how to parse our options. */ + + optStruct3 opt; + + unsigned int option_def_index; + unsigned int outfileSpec; + + MALLOCARRAY_NOFAIL(option_def, 100); + + option_def_index = 0; /* incremented by OPTENTRY */ + OPTENT3(0, "alpha", OPT_FLAG, NULL, &cmdlineP->alpha, 0); + OPTENT3(0, "header", OPT_FLAG, NULL, &cmdlineP->header, 0); + OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); + OPTENT3(0, "outfile", OPT_STRING, &cmdlineP->outfile, + &outfileSpec, 0); + + opt.opt_table = option_def; + opt.short_allowed = false; /* We have no short (old-fashioned) options */ + opt.allowNegNum = false; /* We have no parms that are negative numbers */ + + pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + free(option_def); + + if (argc-1 == 0) + cmdlineP->inFileName = "-"; + else if (argc-1 != 1) { + pm_error("Program takes zero or one argument (filename). You " + "specified %d", argc-1); + } + else + cmdlineP->inFileName = argv[1]; + + if (!outfileSpec) + cmdlineP->outfile = "-"; +} + -#define VPRINTF if (verbose || header) fprintf -typedef unsigned char U_CHAR; -/* - * Global variables. - */ -static FILE *fp; -static rle_hdr hdr; -static int format; -static int width, height; -static int verbose = 0, header = 0, do_alpha = 0; -static gray maxval; -/*----------------------------------------------------------------------------- - * Read the pnm image file header. - */ static void -read_pnm_header(void) { +readPnmHeader(bool const verbose, + bool const wantAlpha, + FILE * const ifP, + int * const widthP, + int * const heightP, + gray * const maxvalP, + int * const formatP) { +/*----------------------------------------------------------------------------- + Read the pnm image file header. +---------------------------------------------------------------------------- */ + int width; + int height; + gray maxval; + int format; + const char * type; + + pnm_readpnminit(ifP, &width, &height, &maxval, &format); - pnm_readpnminit(fp, &width, &height, &maxval, &format); switch (format) { case PBM_FORMAT: - VPRINTF(stderr, "Image type: plain pbm format\n"); + type="plain pbm"; break; case RPBM_FORMAT: - VPRINTF(stderr, "Image type: raw pbm format\n"); + type="raw pbm"; break; case PGM_FORMAT: - VPRINTF(stderr, "Image type: plain pgm format\n"); + type="plain pgm"; break; case RPGM_FORMAT: - VPRINTF(stderr, "Image type: raw pgm format\n"); + type="raw pgm"; break; case PPM_FORMAT: - VPRINTF(stderr, "Image type: plain ppm format\n"); + type="plain ppm"; break; case RPPM_FORMAT: - VPRINTF(stderr, "Image type: raw ppm format\n"); + type="raw ppm"; break; } - VPRINTF(stderr, "Full image: %dx%d\n", width, height); - VPRINTF(stderr, "Maxval: %d\n", maxval); - if (do_alpha) - VPRINTF(stderr, "Computing alpha channel...\n"); + if (verbose) { + pm_message("Image type: %s format", type); + pm_message("Full image: %dx%d", width, height); + pm_message("Maxval: %d", maxval); + + if (wantAlpha) + pm_message("Computing alpha channel..."); + } + *widthP = width; + *heightP = height; + *maxvalP = maxval; + *formatP = format; } static void -write_rle_header(void) { +writeRleHeader(bool const wantAlpha, + int const format, + unsigned int const width, + unsigned int const height, + rle_hdr * const hdrP) { + + rle_hdr hdr; + + hdr = *hdrP; /* initial value */ hdr.xmin = 0; hdr.xmax = width-1; hdr.ymin = 0; hdr.ymax = height-1; hdr.background = 0; + switch (format) { case PBM_FORMAT: case RPBM_FORMAT: @@ -114,31 +200,42 @@ write_rle_header(void) { RLE_SET_BIT(hdr, RLE_BLUE); break; } - if (do_alpha) { + if (wantAlpha) { hdr.alpha = 1; RLE_SET_BIT(hdr, RLE_ALPHA); } rle_put_setup(&hdr); + + *hdrP = hdr; } static void -write_rle_data(void) { +writeRleData(bool const verbose, + bool const wantAlpha, + FILE * const ifP, + rle_hdr * const hdrP, + unsigned int const width, + unsigned int const height, + gray const maxval, + int const format) { unsigned int scan; xel * xelrow; rle_pixel *** scanlines; MALLOCARRAY(xelrow, width); - MALLOCARRAY(scanlines, height); + if (xelrow == NULL) + pm_error("Failed to allocate memory for row of %u pixels", width); - if (!scanlines) + MALLOCARRAY(scanlines, height); + if (scanlines == NULL) pm_error("Failed to allocate memory for %u scanline pointers", height); for (scan = 0; scan < height; ++scan) { int rc; - rc = rle_row_alloc(&hdr, &scanlines[scan]); + rc = rle_row_alloc(hdrP, &scanlines[scan]); if (rc < 0) pm_error("Failed to allocate memory for a scanline"); } @@ -151,10 +248,10 @@ write_rle_data(void) { for (scan = 0; scan < height; ++scan) { rle_pixel ** const scanline = scanlines[height - scan - 1]; unsigned int col; - pnm_readpnmrow(fp, xelrow, width, maxval, format); + pnm_readpnmrow(ifP, xelrow, width, maxval, format); for (col = 0; col < width; ++col) { scanline[RLE_RED][col] = PNM_GET1(xelrow[col]) ? 255 : 0; - if (do_alpha) + if (wantAlpha) scanline[RLE_ALPHA][col] = scanline[RLE_RED][col]; } } @@ -165,10 +262,10 @@ write_rle_data(void) { for (scan = 0; scan < height; ++scan) { rle_pixel ** const scanline = scanlines[height - scan - 1]; unsigned int col; - pnm_readpnmrow(fp, xelrow, width, maxval, format); + pnm_readpnmrow(ifP, xelrow, width, maxval, format); for (col = 0; col < width; ++col) { scanline[RLE_RED][col] = PNM_GET1(xelrow[col]); - if (do_alpha) + if (wantAlpha) scanline[RLE_ALPHA][col] = scanline[RLE_RED][col] ? 255 : 0; } @@ -179,13 +276,16 @@ write_rle_data(void) { unsigned int scan; for (scan = 0; scan < height; scan++) { rle_pixel ** const scanline = scanlines[height - scan - 1]; + unsigned int col; - pnm_readpnmrow(fp, xelrow, width, maxval, format); + + pnm_readpnmrow(ifP, xelrow, width, maxval, format); + for (col = 0; col < width; ++col) { scanline[RLE_RED][col] = PPM_GETR(xelrow[col]); scanline[RLE_GREEN][col] = PPM_GETG(xelrow[col]); scanline[RLE_BLUE][col] = PPM_GETB(xelrow[col]); - if (do_alpha) + if (wantAlpha) scanline[RLE_ALPHA][col] = (scanline[RLE_RED][col] || scanline[RLE_GREEN][col] || @@ -196,25 +296,27 @@ write_rle_data(void) { } /* Write out data in URT order (bottom to top). */ for (scan = 0; scan < height; ++scan) - rle_putrow(scanlines[scan], width, &hdr); + rle_putrow(scanlines[scan], width, hdrP); for (scan = 0; scan < height; ++scan) - rle_row_free(&hdr, scanlines[scan]); + rle_row_free(hdrP, scanlines[scan]); free(scanlines); free(xelrow); - VPRINTF(stderr, "Done -- write eof to RLE data.\n"); - rle_puteof(&hdr); + if (verbose) + pm_message("Done -- write eof to RLE data."); + + rle_puteof(hdrP); } static void -skip_data(FILE * const fp, - int const width, - int const height, - gray const maxval, - int const format) { +skipData(FILE * const ifP, + unsigned int const width, + unsigned int const height, + gray const maxval, + int const format) { xel * xelrow; unsigned int scan; @@ -223,8 +325,8 @@ skip_data(FILE * const fp, if (xelrow == NULL) pm_error("Failed to allocate memory for row of %u pixels", width); - for(scan=0; scan < height; ++scan) - pnm_readpnmrow(fp, xelrow, width, maxval, format); + for (scan=0; scan < height; ++scan) + pnm_readpnmrow(ifP, xelrow, width, maxval, format); free(xelrow); } @@ -232,57 +334,57 @@ skip_data(FILE * const fp, int -main(int argc, char ** argv) { - - const char * pnmname; - const char * outname; - int oflag; +main(int argc, char ** argv) { + + struct CmdlineInfo cmdline; + + FILE * ifP; + rle_hdr hdr; + int format; + int width, height; + gray maxval; + bool verbose; + const char ** argvWork; + unsigned int i; int eof; - pnm_init(&argc, argv); - - pnmname = NULL; /* initial value */ - outname = NULL; /* initial value */ - - /* Get those options. */ - if (!scanargs(argc,argv, - "% v%- h%- a%- o%-outfile!s pnmfile%s\n(\ -\tConvert a PNM file to URT RLE format.\n\ -\t-a\tFake an alpha channel. Alpha=0 when input=0, 255 otherwise.\n\ -\t-h\tPrint header of PNM file and exit.\n\ -\t-v\tVerbose mode.)", - &verbose, - &header, - &do_alpha, - &oflag, &outname, - &pnmname)) - exit(-1); + MALLOCARRAY_NOFAIL(argvWork, argc + 1); + + for (i = 0; i < argc; ++i) /* Make a copy of argv */ + argvWork[i] = argv[i]; + + pm_proginit(&argc, argvWork); + + parseCommandLine(argc, argvWork, &cmdline); + + verbose = cmdline.verbose || cmdline.header; hdr = *rle_hdr_init(NULL); - rle_names(&hdr, cmd_name(argv), outname, 0); + + rle_names(&hdr, "pnmtorle", cmdline.outfile, 0); /* Open the file. */ - if (pnmname == NULL) { - fp = pm_openr("-"); - } else { - fp = pm_openr(pnmname); - } + assert(cmdline.inFileName != NULL); + ifP = pm_openr(cmdline.inFileName); - hdr.rle_file = rle_open_f( hdr.cmd, outname, "wb" ); + hdr.rle_file = rle_open_f(hdr.cmd, cmdline.outfile, "wb"); for (eof = 0; !eof; ) { - read_pnm_header(); + readPnmHeader(verbose, cmdline.alpha, ifP, + &width, &height, &maxval, &format); - if (header) - skip_data(fp, width, height, maxval, format); - else { + if (cmdline.header) { + skipData(ifP, width, height, maxval, format); + } else { rle_addhist(argv, NULL, &hdr); - write_rle_header(); - write_rle_data(); + writeRleHeader(cmdline.alpha, format, width, height, &hdr); + writeRleData(verbose, cmdline.alpha, ifP, &hdr, + width, height, maxval, format); } - pnm_nextimage(fp, &eof); + pnm_nextimage(ifP, &eof); } - pm_close(fp); + + pm_close(ifP); return 0; } diff --git a/converter/other/pnmtosir.c b/converter/other/pnmtosir.c index 20bb6178..7b7650fe 100644 --- a/converter/other/pnmtosir.c +++ b/converter/other/pnmtosir.c @@ -20,16 +20,16 @@ int main(int argc, const char * argv[]) { - + FILE * ifP; xel ** xels; int rows, cols, format; unsigned int n; bool isGrayscale; xelval maxval; - unsigned short Header[16]; - unsigned short LutHeader[16]; - unsigned short Lut[2048]; + unsigned short Header[10]; + unsigned short LutHeader[5]; + unsigned short Lut[1024]; pm_proginit(&argc, argv); @@ -43,9 +43,9 @@ main(int argc, const char * argv[]) { } else { ifP = stdin; } - + xels = pnm_readpnm(ifP, &cols, &rows, &maxval, &format); - + /* Figure out the colormap. */ switch (PNM_FORMAT_TYPE(format) ) { case PPM_TYPE: @@ -93,15 +93,19 @@ main(int argc, const char * argv[]) { pm_writelittleshort(stdout,LutHeader[n]); for (n = 5; n < 256; ++n) pm_writelittleshort(stdout,0); - - for (n = 0; n < 3; ++n) { + + for (n = 0; n < 256; ++n) { unsigned int m; - for (m = 0; m < 256; ++m) - Lut[m * 4 + n] = m << 8; + for (m = 0; m < 3; ++m) + Lut[n * 4 + m] = n << 8; + + Lut[n * 4 + 3] = 0; + /* Clear to ensure repeatable output, suppress Valgrind error */ } + for (n = 0; n < 1024; ++n) pm_writelittleshort(stdout,Lut[n]); - + /* Finally, write out the data. */ switch (PNM_FORMAT_TYPE(format)) { case PPM_TYPE: { @@ -110,13 +114,13 @@ main(int argc, const char * argv[]) { unsigned int col; for (col = 0; col < cols; ++col) { unsigned char const ub = - (char) (PPM_GETR(xels[row][col]) * (255 / maxval)); + (char) (PPM_GETR(xels[row][col]) * (255 / maxval)); fputc(ub, stdout); } } for (row = 0; row < rows; ++row) { unsigned int col; - for (col = 0; col < cols; ++col) { + for (col = 0; col < cols; ++col) { unsigned const char ub = (char) (PPM_GETG(xels[row][col]) * (255 / maxval)); fputc(ub, stdout); @@ -124,7 +128,7 @@ main(int argc, const char * argv[]) { } for (row = 0; row < rows; ++row) { unsigned int col; - for (col = 0; col < cols; ++col) { + for (col = 0; col < cols; ++col) { unsigned const char ub = (char) (PPM_GETB(xels[row][col]) * (255 / maxval)); fputc(ub, stdout); @@ -144,10 +148,11 @@ main(int argc, const char * argv[]) { } } break; } - + pm_close(ifP); return 0; } + |