/home/fwph/code/wurde/rde/utils/rleCoding.cpp

Go to the documentation of this file.
00001 
00005 #include <RobotTypes.H>
00006 #include <ImageSource.H>
00007 
00008 namespace WURDE {
00009        /*
00010          RLE Encodes an array of unsigned chars in place.  In order to speed things up, you can
00011          pass in a pointer to a buffer (at least as large as the original data) that is just
00012          used as garbage space.
00013 
00014          Note, if the encoding does not produce a shorter array, then the
00015          original array is returned, and the function returns the length of the array.
00016          
00017          If the encoding does produce a shorter array, then the RLE encoded array is returned and
00018          the function returns the length of the encoded array.
00019        */
00020        long GCM_rleEncodeGreyLow(unsigned char *data, const long rows, const long cols) {
00021               long i, j;
00022               unsigned char curRun, curVal;
00023               unsigned char *source = data;
00024               unsigned char *target = data;
00025               long count = 0;
00026               
00027               count = 0;
00028               for(i=0;i<rows*cols;) {
00029                      
00030                      // grab the current pixel as the current run exemplar
00031                      curVal = source[i++] >> 3;
00032 
00033                      // the current run starts out as 1
00034                      curRun = 0;
00035                      for(j=0;j<7 && i<rows*cols;j++) {
00036                             if((source[i] >> 3) == curVal) {
00037                                    curRun++;
00038                                    i++;
00039                             }
00040                             else
00041                                    break;
00042                      }
00043 
00044                      target[count++] = (curRun << 5) | curVal;
00045               }
00046 
00047               return(count);
00048        }
00049 
00050 
00051        /*
00052          Decodes from the source to the target memory 
00053 
00054          The target memory must be large enough to hold the whole image
00055        */
00056        int GCM_rleDecodeGreyLow(unsigned char *source, const long rleSize, unsigned char *target) {
00057               long i, j;
00058               unsigned long k;
00059               unsigned int curRun;
00060               unsigned char curVal;
00061 
00062               for(i=0,j=0;i<rleSize;i++) {
00063 
00064                      // get the current run/value information
00065                      curRun = (source[i] >> 5) + 1;
00066                      curVal = (source[i]) << 3;
00067     
00068                      // fill it out in the temporary image
00069                      for(k=0;k<curRun;k++,j++)
00070                             target[j] = curVal;
00071               }
00072 
00073               return(0);
00074        }
00075 
00076 
00077        /*
00078          Middle quality encoding of greyscale images.
00079   
00080          Each 8-bit value is 2-bits of run information and 6 bits of value
00081        */
00082        long GCM_rleEncodeGreyMed(unsigned char *data, const long rows, const long cols) {
00083               long i, j;
00084               unsigned char curRun, curVal;
00085               unsigned char *source = data;
00086               unsigned char *target = data;
00087               long count = 0;
00088 
00089               count = 0;
00090               for(i=0;i<rows*cols;) {
00091 
00092                      // grab the current pixel as the current run exemplar
00093                      curVal = source[i++] >> 2;
00094 
00095                      // the current run starts out as 1
00096                      curRun = 0;
00097                      for(j=0;j<3 && i<rows*cols;j++) {
00098                             if((source[i] >> 2) == curVal) {
00099                                    curRun++;
00100                                    i++;
00101                             }
00102                             else
00103                                    break;
00104                      }
00105 
00106                      target[count++] = (curRun << 6) | curVal;
00107               }
00108 
00109               return(count);
00110        }
00111 
00112 
00113        /*
00114          Decodes a medium quality RLE image from the source to the target
00115        */
00116        int GCM_rleDecodeGreyMed(unsigned char *source, const long rleSize, unsigned char *target) {
00117               long i, j;
00118               unsigned long k;
00119               unsigned int curRun;
00120               unsigned char curVal;
00121 
00122               for(i=0,j=0;i<rleSize;i++) {
00123 
00124                      // get the current run/value information
00125                      curRun = (source[i] >> 6) + 1;
00126                      curVal = (source[i]) << 2;
00127     
00128                      // fill it out in the temporary image
00129                      for(k=0;k<curRun;k++,j++)
00130                             target[j] = curVal;
00131               }
00132 
00133               return(0);
00134        }
00135 
00136        /*
00137          Low quality encoding of color images.
00138   
00139          Each similar run of 3-byte pixels is encoded into a 2-byte value 
00140 
00141          4-bits of run information, followed by a 4/4/4 R/G/B color value
00142 
00143          This code works on the array in place
00144        */
00145        long GCM_rleEncodePixLow(unsigned char *data, const long rows, const long cols) {
00146               long a,i;
00147               unsigned short curRun, curVal;
00148               unsigned char *source = data;
00149               unsigned char *target = data;
00150               long count = 0;
00151 
00152               count = 0;
00153               for(i=0;i<rows*cols*3;) {
00154 
00155                      // grab the current pixel as the current run exemplar
00156                      curVal = ((source[i] & 0x00F0) << 4) | ((source[i+1] & 0x00F0)) | ((source[i+2] & 0x00F0) >> 4);
00157                      a = i;
00158                      i += 3;
00159 
00160                      // max value for curRun is 15
00161                      for(curRun=0;curRun<15 && i<rows*cols*3;curRun++,i+=3) {
00162                             if(curVal != (((source[i] & 0x00F0) << 4) | ((source[i+1] & 0x00F0)) | ((source[i+2] & 0x00F0) >> 4)))
00163                                    break;
00164                      }
00165 
00166                      target[count++] = (curRun << 4) | ((source[a] & 0xF0) >> 4);
00167                      target[count++] = (source[a+1] & 0xF0) | ((source[a+2] & 0xF0) >> 4);
00168               }
00169 
00170               return(count); // number of bytes
00171        }
00172 
00173 
00174        /*
00175          Decodes a low quality color RLE image from the source to the target memory.
00176        */
00177        int GCM_rleDecodePixLow(unsigned char *data, const long rleSize, unsigned char *target) {
00178               long i, j;
00179               short curRun;
00180               unsigned char curVal[3];
00181               unsigned char *source = (unsigned char *)data;
00182 
00183               for(i=0,j=0;i<rleSize;i+=2) {
00184 
00185                      // get the current run/value information
00186                      curRun = ((source[i] & 0xF0) >> 4);
00187                      curVal[0] = (source[i] & 0x0F) << 4;
00188                      curVal[1] = (source[i+1] & 0xF0);
00189                      curVal[2] = (source[i+1] & 0x0F) << 4;
00190 
00191                      // fill it out in the temporary image
00192                      for(;curRun>=0;curRun--,j+=3) {
00193                             target[j+0] = curVal[0];
00194                             target[j+1] = curVal[1];
00195                             target[j+2] = curVal[2];
00196                      }
00197               }
00198 
00199               return(0);
00200        }
00201 
00202 
00203        /*
00204          Medium quality encoding of color images.
00205   
00206          Each 3-byte pixel value is encoded into a 2-byte value (short) value
00207 
00208          No run information, color is a 5/6/5 R/G/B color value
00209 
00210          This code works on the array in place
00211        */
00212        long GCM_rleEncodePixMed(unsigned char *data, const long rows, const long cols) {
00213               long i;
00214               unsigned char *source = data;
00215               unsigned char *target = (unsigned char *)data;
00216               long count = 0;
00217 
00218               for(i=0,count=0;i<rows*cols*3;i+=3) {
00219 
00220                      // first byte gets 5 bits of red, and 3 bits of green
00221                      target[count++] = (source[i] & 0xF8) | (source[i+1] >> 5);
00222 
00223                      // second byte gets 3 bits of green and 5 bits of blue
00224                      target[count++] = ((source[i+1] & 0xFC) << 3) | (source[i+2] >> 3);
00225               }
00226 
00227               return(count); // number of bytes
00228        }
00229 
00230 
00231        /*
00232          Decodes a medium quality color image
00233 
00234          Copies from the source to the target
00235        */
00236        int GCM_rleDecodePixMed(unsigned char *data, const long rleSize, unsigned char *target) {
00237               long i, j;
00238               unsigned char *source = (unsigned char *)data;
00239 
00240               // rleSize/2 because rleSize is number of bytes
00241               for(i=0,j=0;i<rleSize;i+=2,j+=3) {
00242                      // unpack the colors
00243                      target[j+0] = (source[i] & 0xF8);
00244                      target[j+1] = ((source[i] & 0x07) << 5) | ((source[i+1] & 0xE0) >> 3);
00245                      target[j+2] = (source[i+1] & 0x1F) << 3; 
00246               }
00247 
00248               return(0);
00249        }
00250 
00251 }

Generated on Thu Feb 1 15:31:54 2007 for WURDE by  doxygen 1.5.1