about summary refs log tree commit diff
path: root/converter/pbm
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2006-09-14 15:46:23 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2006-09-14 15:46:23 +0000
commite6df671fd2cefb57016be998590b2fc9645e5c38 (patch)
tree45cdcb449a13c2dc320a5dacba445e4683c447e5 /converter/pbm
parent7bd77004a7a252e5e33309944e04e70dc7fd8c46 (diff)
downloadnetpbm-mirror-e6df671fd2cefb57016be998590b2fc9645e5c38.tar.gz
netpbm-mirror-e6df671fd2cefb57016be998590b2fc9645e5c38.tar.xz
netpbm-mirror-e6df671fd2cefb57016be998590b2fc9645e5c38.zip
plain NPM, 8 byte padding, 120 byte text limit from Paul Bolle
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@54 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/pbm')
-rw-r--r--converter/pbm/pbmtonokia.c103
1 files changed, 94 insertions, 9 deletions
diff --git a/converter/pbm/pbmtonokia.c b/converter/pbm/pbmtonokia.c
index 47745288..3c47eac3 100644
--- a/converter/pbm/pbmtonokia.c
+++ b/converter/pbm/pbmtonokia.c
@@ -6,6 +6,7 @@
 
 #define _BSD_SOURCE    /* Make sure strcasecmp() is in string.h */
 #include <string.h>
+#include <assert.h>
 
 #include "pm_c_util.h"
 #include "nstring.h"
@@ -18,7 +19,8 @@ enum outputFormat {
     FMT_HEX_NGG,
     FMT_HEX_NPM,
     FMT_NOL,
-    FMT_NGG
+    FMT_NGG,
+    FMT_NPM
 };
 
 
@@ -104,9 +106,11 @@ parseCommandLine(int argc, char ** argv,
             cmdlineP->outputFormat = FMT_NOL;
         else if (STRCASEEQ(fmtOpt, "NGG"))
             cmdlineP->outputFormat = FMT_NGG;
+        else if (STRCASEEQ(fmtOpt, "NPM"))
+            cmdlineP->outputFormat = FMT_NPM;
         else
-            pm_error("-fmt option must be HEX_NOL, HEX_NGG, HEX_NPM, "
-                     "NOL, or NGG.  You specified '%s'", fmtOpt);
+            pm_error("-fmt option must be HEX_NGG, HEX_NOL, HEX_NPM, "
+                     "NGG, NOL or NPM.  You specified '%s'", fmtOpt);
     } else
         cmdlineP->outputFormat = FMT_HEX_NOL;
 
@@ -124,12 +128,16 @@ parseCommandLine(int argc, char ** argv,
 
     if (!txtSpec)
         cmdlineP->txt = NULL;
+    else if (strlen(cmdlineP->txt) > 120)
+        pm_error("Text message is longer (%u characters) than "
+                 "the 120 characters allowed by the format.",
+                 strlen(cmdlineP->txt));
 
     if (argc-1 == 0) 
         cmdlineP->inputFileName = "-";
     else if (argc-1 != 1)
         pm_error("Program takes zero or one argument (filename).  You "
-                 "specified %d", argc-1);
+                 "specified %u", argc-1);
     else
         cmdlineP->inputFileName = argv[1];
 }
@@ -267,6 +275,7 @@ convertToNol(bit **       const image,
 
     unsigned int row;
     char header[32];
+    unsigned int it;
     
     /* header - this is a hack */
 
@@ -305,6 +314,10 @@ convertToNol(bit **       const image,
             putc(output, ofP);
         }
     }
+
+    /* padding (to keep gnokii happy) */
+    for (it = 0; it < 8 - cols * rows % 8; ++it)
+        putc('0', ofP);
 }
 
 
@@ -318,6 +331,7 @@ convertToNgg(bit **       const image,
 
     unsigned int row;
     char    header[32];
+    unsigned int it;
 
     /* header - this is a hack */
 
@@ -353,6 +367,74 @@ convertToNgg(bit **       const image,
             putc(output, ofP);
         }
     }
+
+    /* padding (to keep gnokii happy) */
+    for (it = 0; it < 8 - cols * rows % 8; ++it)
+        putc('0', ofP);
+}
+
+
+
+static void
+convertToNpm(bit **       const image,
+             unsigned int const cols,
+             unsigned int const rows,
+             const char * const text,
+             FILE *       const ofP) {
+
+    unsigned int row;
+    char header[132];
+    size_t len;
+
+    if (text) 
+        len = strlen(text);
+    else
+        len = 0;
+
+    /* header and optional text */
+
+    header[       0] = 'N';
+    header[       1] = 'P';
+    header[       2] = 'M';
+    header[       3] = 0;
+    header[       4] = len;
+    header[       5] = 0;
+    memcpy(&header[5], text, len);
+    header[ 6 + len] = cols;
+    header[ 7 + len] = rows;
+    header[ 8 + len] = 1;
+    header[ 9 + len] = 1;
+    header[10 + len] = 0; /* unknown */
+
+    assert(10 + len < sizeof(header));
+
+    fwrite(header, 11 + len, 1, ofP);
+    
+    /* image: stream of bits, each row padded to a byte boundary
+       inspired by gnokii/common/gsm-filesystems.c
+     */
+    for (row = 0; row < rows; row++) {
+        unsigned int byteNumber;
+        int bitNumber;
+        char buffer[32];  /* picture messages are (always?) 72 x 28 */
+        unsigned int col;
+
+        byteNumber = 0;
+        bitNumber = 7;
+
+        MEMSZERO(buffer);
+
+        for (col = 0; col < cols; ++col) {
+            if (image[row][col] == PBM_BLACK)
+                buffer[byteNumber] |= (1 << bitNumber);
+            --bitNumber;
+            if (bitNumber < 0 && col < (cols - 1)) {
+                bitNumber = 7;
+                ++byteNumber;
+            }
+        }
+        fwrite(buffer, byteNumber + 1, 1, ofP);
+    }
 }
 
 
@@ -375,20 +457,23 @@ main(int    argc,
     pm_close(ifP);
 
     switch (cmdline.outputFormat) {
-    case FMT_HEX_NOL:
-        convertToHexNol(bits, cols, rows, cmdline.networkCode, stdout);
-        break;
     case FMT_HEX_NGG:
         convertToHexNgg(bits, cols, rows, stdout);
         break;
+    case FMT_HEX_NOL:
+        convertToHexNol(bits, cols, rows, cmdline.networkCode, stdout);
+        break;
     case FMT_HEX_NPM:
         convertToHexNpm(bits, cols, rows, cmdline.txt, stdout);
         break;
+    case FMT_NGG:
+        convertToNgg(bits, cols, rows, stdout);
+        break;
     case FMT_NOL:
         convertToNol(bits, cols, rows, stdout);
         break;
-    case FMT_NGG:
-        convertToNgg(bits, cols, rows, stdout);
+    case FMT_NPM:
+        convertToNpm(bits, cols, rows, cmdline.txt, stdout);
         break;
     }