about summary refs log tree commit diff
path: root/editor/pamenlarge.c
diff options
context:
space:
mode:
Diffstat (limited to 'editor/pamenlarge.c')
-rw-r--r--editor/pamenlarge.c146
1 files changed, 121 insertions, 25 deletions
diff --git a/editor/pamenlarge.c b/editor/pamenlarge.c
index b3039424..187bfb6e 100644
--- a/editor/pamenlarge.c
+++ b/editor/pamenlarge.c
@@ -115,6 +115,8 @@ enlargePbmRowHorizontally(struct pam *          const inpamP,
     static unsigned char const trp3[8] = { 
         0x00, 0x07, 0x38, 0x3F, 0xC0, 0xC7, 0xF8, 0xFF };
 
+    static unsigned char const quad[4] = { 0x00, 0x0F, 0xF0, 0xFF };
+
     static unsigned char const quin2[8] = {
         0x00, 0x01, 0x3E, 0x3F, 0xC0, 0xC1, 0xFE, 0xFF };
 
@@ -129,33 +131,127 @@ enlargePbmRowHorizontally(struct pam *          const inpamP,
     case 1:  break; /* outrow set to inrow */
     case 2:  /* Make outrow using prefabricated parts (same for 3, 5). */ 
         for (colChar = 0; colChar < inColChars; ++colChar) { 
-            outrow[colChar*2]  = dbl[(inrow[colChar] & 0xF0) >> 4];
-            outrow[colChar*2+1]= dbl[inrow[colChar] & 0x0F];
+            outrow[colChar*2]   = dbl[(inrow[colChar] & 0xF0) >> 4];
+            outrow[colChar*2+1] = dbl[(inrow[colChar] & 0x0F) >> 0];
             /* Possible outrow overrun by one byte. */
         }
-        break;   
+        break;
+
     case 3:
         for (colChar = 0; colChar < inColChars; ++colChar) { 
-            outrow[colChar*3]  = trp1[(inrow[colChar] & 0xF0) >> 5];
-            outrow[colChar*3+1]= trp2[(inrow[colChar] >> 2) & 0x0F];
-            outrow[colChar*3+2]= trp3[inrow[colChar] & 0x07];
+            outrow[colChar*3]   = trp1[(inrow[colChar] & 0xF0) >> 5];
+            outrow[colChar*3+1] = trp2[(inrow[colChar] >> 2) & 0x0F];
+            outrow[colChar*3+2] = trp3[(inrow[colChar] >> 0) & 0x07];
         }
         break;  
+
+    case 4:
+        for (colChar = 0; colChar < inColChars; ++colChar) {
+            unsigned int i;
+            for (i = 0; i < 4; ++i) 
+                outrow[colChar*4+i]=
+                    quad[(inrow[colChar] >> (6 - 2 * i)) & 0x03]; 
+        }
+        break;
+
     case 5:
         for (colChar = 0; colChar < inColChars; ++colChar) { 
-            outrow[colChar*5]  = pair[ (inrow[colChar] >>6) & 0x03 ] >> 5; 
-            outrow[colChar*5+1]= quin2[(inrow[colChar] >>4) & 0x07 ]; 
-            outrow[colChar*5+2]= pair[ (inrow[colChar] >>3) & 0x03 ] >> 4; 
-            outrow[colChar*5+3]= quin4[(inrow[colChar] >>1) & 0x07 ];
-            outrow[colChar*5+4]= pair[ inrow[colChar] & 0x03 ] >>3; 
+            outrow[colChar*5]   = pair [(inrow[colChar] >> 6) & 0x03] >> 5; 
+            outrow[colChar*5+1] = quin2[(inrow[colChar] >> 4) & 0x07] >> 0; 
+            outrow[colChar*5+2] = quad [(inrow[colChar] >> 3) & 0x03] >> 0; 
+            outrow[colChar*5+3] = quin4[(inrow[colChar] >> 1) & 0x07] >> 0;
+            outrow[colChar*5+4] = pair [(inrow[colChar] >> 0) & 0x03] >> 3; 
+        }
+        break;
+
+    case 6:  /* Compound of 2 and 3 */ 
+        for (colChar = 0; colChar < inColChars; ++colChar) { 
+            unsigned char const hi = dbl[(inrow[colChar] & 0xF0) >> 4];
+            unsigned char const lo = dbl[(inrow[colChar] & 0x0F) >> 0];
+
+            outrow[colChar*6]   = trp1[(hi & 0xF0) >> 5];
+            outrow[colChar*6+1] = trp2[(hi >> 2) & 0x0F];
+            outrow[colChar*6+2] = trp3[hi & 0x07];
+
+            outrow[colChar*6+3] = trp1[(lo & 0xF0) >> 5];
+            outrow[colChar*6+4] = trp2[(lo >> 2) & 0x0F];
+            outrow[colChar*6+5] = trp3[lo & 0x07];
+        }
+        break;  
+
+    case 7:
+        for (colChar = 0; colChar < inColChars; ++colChar) { 
+            uint32_t hi, lo;
+
+            hi = inrow[colChar] >> 4;
+            hi = ((((hi>>1) * 0x00082080) | (0x01 & hi)) & 0x00204081 ) * 0x7F;
+            hi >>= 4;
+            outrow[colChar*7]   =  (unsigned char) ( hi >> 16);
+            outrow[colChar*7+1] =  (unsigned char) ((hi >>  8) & 0xFF);
+            outrow[colChar*7+2] =  (unsigned char) ((hi >>  0) & 0xFF);
+
+            lo = inrow[colChar] & 0x001F;
+            lo = ((((lo>>1) * 0x02082080) | (0x01 & lo)) & 0x10204081 ) * 0x7F;
+            outrow[colChar*7+3] =  (unsigned char) ((lo >> 24) & 0xFF);
+            outrow[colChar*7+4] =  (unsigned char) ((lo >> 16) & 0xFF); 
+            outrow[colChar*7+5] =  (unsigned char) ((lo >>  8) & 0xFF);
+            outrow[colChar*7+6] =  (unsigned char) ((lo >>  0) & 0xFF);
         }
         break;
-    case 4: default:
-        /*  Unlike the above cases, we iterate through outrow.  The color
-            composition of each outrow byte is computed by consulting
-            a single bit or two consecutive bits in inrow. 
+
+    case 8:
+        for (colChar = 0; colChar < inColChars; ++colChar) { 
+            unsigned int i;
+            for (i = 0; i < 8; ++i) {
+                outrow[colChar*8+i] =
+                    ((inrow[colChar] >> (7-i)) & 0x01) *0xFF;
+            }
+        }
+        break;
+
+    case 9:
+        for (colChar = 0; colChar < inColChars; ++colChar) { 
+            outrow[colChar*9]   =  ((inrow[colChar] >> 7) & 0x01) * 0xFF;
+            outrow[colChar*9+1] =  pair[(inrow[colChar] >> 6) & 0x03] >> 1; 
+            outrow[colChar*9+2] =  pair[(inrow[colChar] >> 5) & 0x03] >> 2; 
+            outrow[colChar*9+3] =  pair[(inrow[colChar] >> 4) & 0x03] >> 3; 
+            outrow[colChar*9+4] =  pair[(inrow[colChar] >> 3) & 0x03] >> 4; 
+            outrow[colChar*9+5] =  pair[(inrow[colChar] >> 2) & 0x03] >> 5; 
+            outrow[colChar*9+6] =  pair[(inrow[colChar] >> 1) & 0x03] >> 6; 
+            outrow[colChar*9+7] =  pair[(inrow[colChar] >> 0) & 0x03] >> 7; 
+            outrow[colChar*9+8] =  (inrow[colChar] & 0x01) * 0xFF;
+        }
+        break;
+
+    case 10:
+        for (colChar = 0; colChar < inColChars; ++colChar) { 
+            outrow[colChar*10]   = ((inrow[colChar] >> 7) & 0x01 ) * 0xFF;
+            outrow[colChar*10+1] = pair[(inrow[colChar] >> 6) & 0x03] >> 2; 
+            outrow[colChar*10+2] = pair[(inrow[colChar] >> 5) & 0x03] >> 4; 
+            outrow[colChar*10+3] = pair[(inrow[colChar] >> 4) & 0x03] >> 6;
+            outrow[colChar*10+4] = ((inrow[colChar] >> 4) & 0x01) * 0xFF;
+            outrow[colChar*10+5] = ((inrow[colChar] >> 3) & 0x01) * 0xFF; 
+            outrow[colChar*10+6] = pair[(inrow[colChar] >> 2) & 0x03] >> 2; 
+            outrow[colChar*10+7] = pair[(inrow[colChar] >> 1) & 0x03] >> 4; 
+            outrow[colChar*10+8] = pair[(inrow[colChar] >> 0) & 0x03] >> 6; 
+            outrow[colChar*10+9] = ((inrow[colChar] >> 0) & 0x01) * 0xFF;
+        }
+        break;
+ 
+
+    default:
+        /*  Unlike the above cases, we iterate through outrow.  To compute the
+            color composition of each outrow byte, we consult a single bit or
+            two consecutive bits in inrow.
+
             Color changes never happen twice in a single outrow byte.
+
+            This is a generalization of above routines for scale factors
+            9 and 10.
+
+            Logic works for scale factors 4, 6, 7, 8, and above (but not 5).
         */
+
         for (colChar = 0; colChar < outColChars; ++colChar) {
             unsigned int const mult = scaleFactor;
             unsigned int const mod = colChar % mult;
@@ -199,12 +295,14 @@ enlargePbm(struct pam * const inpamP,
     
     if (scaleFactor == 1)
         outrow = inrow;
-    else  
-        outrow = pbm_allocrow_packed(outcols + 32);
-            /* The 32 (=4 bytes) is to allow writes beyond outrow data
-               end when scaleFactor is 2, 3, 5.  (max 4 bytes when
-               scaleFactor is 5)
-            */
+    else  {
+        /* Allow writes beyond outrow data end when scaleFactor is
+           one of the special fast cases: 2, 3, 4, 5, 6, 7, 8, 9, 10.
+        */
+        unsigned int const rightPadding = 
+            scaleFactor > 10 ? 0 : (scaleFactor - 1) * 8;  
+        outrow = pbm_allocrow_packed(outcols + rightPadding);
+    }
 
     pbm_writepbminit(ofP, outcols, outrows, 0);
     
@@ -214,10 +312,8 @@ enlargePbm(struct pam * const inpamP,
         pbm_readpbmrow_packed(inpamP->file, inrow, inpamP->width,
                               inpamP->format);
 
-        if (inpamP->width % 8 > 0) {  /* clean final partial byte */ 
-            inrow[inColChars-1] >>= 8 - inpamP->width % 8;
-            inrow[inColChars-1] <<= 8 - inpamP->width % 8;
-        }
+        if (outcols % 8 > 0)           /* clean final partial byte */ 
+            pbm_cleanrowend_packed(inrow, inpamP->width);
 
         enlargePbmRowHorizontally(inpamP, inrow, inColChars, outColChars,
                                   scaleFactor, outrow);