LCOV - code coverage report
Current view: directory - frmts/blx - blx.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 710 578 81.4 %
Date: 2011-12-18 Functions: 39 38 97.4 %

       1                 : /* libblx - Magellan BLX topo reader/writer library
       2                 :  *
       3                 :  * Copyright (c) 2008, Henrik Johansson <henrik@johome.net>
       4                 :  *
       5                 :  * Permission is hereby granted, free of charge, to any person
       6                 :  * obtaining a copy of this software and associated documentation
       7                 :  * files (the "Software"), to deal in the Software without
       8                 :  * restriction, including without limitation the rights to use,
       9                 :  * copy, modify, merge, publish, distribute, sublicense, and/or sell
      10                 :  * copies of the Software, and to permit persons to whom the
      11                 :  * Software is furnished to do so, subject to the following
      12                 :  * conditions:
      13                 :  * 
      14                 :  * The above copyright notice and this permission notice shall be
      15                 :  * included in all copies or substantial portions of the Software.
      16                 :  * 
      17                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      18                 :  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
      19                 :  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      20                 :  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
      21                 :  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
      22                 :  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      23                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      24                 :  * OTHER DEALINGS IN THE SOFTWARE.
      25                 :  */
      26                 : 
      27                 : #include "blx.h"
      28                 : #include <stdio.h>
      29                 : #include <string.h>
      30                 : #include <stdlib.h>
      31                 : 
      32                 : /* Constants */
      33                 : #define MAXLEVELS 5
      34                 : #define MAXCOMPONENTS 4
      35                 : 
      36                 : static const int table1[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      37                 :       ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      38                 :       ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      39                 :       ,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
      40                 :       ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
      41                 :       ,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2
      42                 :       ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
      43                 :       ,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
      44                 :       ,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5
      45                 :       ,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7
      46                 :       ,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10
      47                 :       ,11,11,11,11,12,12,12,12,13,13,13,13,14
      48                 :       ,14,15,15,16,16,17,17,18,18,19,19,20,21
      49                 :       ,22,23,24,25,26,27,28,29,30,31,255,255,255
      50                 :       ,255,255,255,255,255,255,255,255,255,255,255
      51                 :       ,255,255,255,255,255,255,255,255,255,255};
      52                 : 
      53                 : /* { byte, n of bits when compressed, bit pattern << (13-n of bits) } */
      54                 : static const int table2[][3] = {{0,2,0}, {255,3,2048}, {1,3,3072}, {2,4,4096}, 
      55                 :         {3,4,4608}, {254,5,5120}, {4,5,5376}, {5,5,5632}, 
      56                 :         {253,6,5888}, {6,6,6016}, {252,6,6144}, {7,6,6272}, 
      57                 :         {251,6,6400}, {8,6,6528}, {9,7,6656}, {250,7,6720}, 
      58                 :         {10,7,6784}, {249,7,6848}, {11,7,6912}, {248,7,6976}, 
      59                 :         {12,8,7040}, {247,8,7072}, {16,8,7104}, {246,8,7136}, 
      60                 :         {13,8,7168}, {245,8,7200}, {14,8,7232}, {244,8,7264}, 
      61                 :         {15,8,7296}, {243,8,7328}, {242,8,7360}, {241,8,7392}, 
      62                 :         {17,9,7424}, {18,9,7440}, {240,9,7456}, {239,9,7472}, 
      63                 :         {19,9,7488}, {238,9,7504}, {20,9,7520}, {237,9,7536}, 
      64                 :         {21,9,7552}, {236,9,7568}, {22,9,7584}, {235,9,7600}, 
      65                 :         {234,9,7616}, {23,9,7632}, {233,9,7648}, {24,10,7664}, 
      66                 :         {232,10,7672}, {231,10,7680}, {25,10,7688}, {230,10,7696}, 
      67                 :         {229,10,7704}, {26,10,7712}, {228,10,7720}, {27,10,7728}, 
      68                 :         {227,10,7736}, {225,10,7744}, {226,10,7752}, {28,10,7760}, 
      69                 :         {29,10,7768}, {224,10,7776}, {30,10,7784}, {31,10,7792}, 
      70                 :         {223,10,7800}, {32,10,7808}, {222,10,7816}, {33,10,7824}, 
      71                 :         {221,11,7832}, {220,11,7836}, {34,11,7840}, {219,11,7844}, 
      72                 :         {35,11,7848}, {218,11,7852}, {256,11,7856}, {36,11,7860}, 
      73                 :         {217,11,7864}, {216,11,7868}, {37,11,7872}, {215,11,7876}, 
      74                 :         {38,11,7880}, {214,11,7884}, {193,11,7888}, {213,11,7892}, 
      75                 :         {39,11,7896}, {128,11,7900}, {212,11,7904}, {40,11,7908}, 
      76                 :         {194,11,7912}, {211,11,7916}, {210,11,7920}, {41,11,7924}, 
      77                 :         {209,11,7928}, {208,11,7932}, {42,11,7936}, {207,11,7940}, 
      78                 :         {43,11,7944}, {195,11,7948}, {206,11,7952}, {205,11,7956}, 
      79                 :         {204,11,7960}, {44,11,7964}, {203,11,7968}, {192,11,7972}, 
      80                 :         {196,11,7976}, {45,11,7980}, {201,11,7984}, {200,11,7988}, 
      81                 :         {197,11,7992}, {202,11,7996}, {127,11,8000}, {199,11,8004}, 
      82                 :         {198,11,8008}, {46,12,8012}, {47,12,8014}, {48,12,8016}, 
      83                 :         {49,12,8018}, {50,12,8020}, {51,12,8022}, {191,12,8024}, 
      84                 :         {52,12,8026}, {183,12,8028}, {53,12,8030}, {54,12,8032}, 
      85                 :         {55,12,8034}, {190,12,8036}, {56,12,8038}, {57,12,8040}, 
      86                 :         {189,12,8042}, {58,12,8044}, {176,12,8046}, {59,12,8048}, 
      87                 :         {126,12,8050}, {60,12,8052}, {188,12,8054}, {61,12,8056}, 
      88                 :         {63,12,8058}, {62,12,8060}, {64,12,8062}, {129,12,8064}, 
      89                 :         {187,12,8066}, {186,12,8068}, {65,12,8070}, {66,12,8072}, 
      90                 :         {185,12,8074}, {184,12,8076}, {68,12,8078}, {174,12,8080}, 
      91                 :         {67,12,8082}, {182,13,8084}, {69,13,8085}, {180,13,8086}, 
      92                 :         {181,13,8087}, {71,13,8088}, {70,13,8089}, {179,13,8090}, 
      93                 :         {125,13,8091}, {72,13,8092}, {130,13,8093}, {178,13,8094}, 
      94                 :         {177,13,8095}, {73,13,8096}, {74,13,8097}, {124,13,8098}, 
      95                 :         {76,13,8099}, {175,13,8100}, {75,13,8101}, {131,13,8102}, 
      96                 :         {132,13,8103}, {79,13,8104}, {77,13,8105}, {123,13,8106}, 
      97                 :         {80,13,8107}, {172,13,8108}, {171,13,8109}, {78,13,8110}, 
      98                 :         {173,13,8111}, {81,13,8112}, {169,13,8113}, {122,13,8114}, 
      99                 :         {82,13,8115}, {133,13,8116}, {168,13,8117}, {84,13,8118}, 
     100                 :         {164,13,8119}, {167,13,8120}, {85,13,8121}, {170,13,8122}, 
     101                 :         {166,13,8123}, {165,13,8124}, {121,13,8125}, {160,13,8126}, 
     102                 :         {134,13,8127}, {136,13,8128}, {161,13,8129}, {120,13,8130}, 
     103                 :         {88,13,8131}, {83,13,8132}, {119,13,8133}, {163,13,8134}, 
     104                 :         {162,13,8135}, {159,13,8136}, {91,13,8137}, {135,13,8138}, 
     105                 :         {90,13,8139}, {86,13,8140}, {137,13,8141}, {87,13,8142}, 
     106                 :         {89,13,8143}, {158,13,8144}, {152,13,8145}, {138,13,8146}, 
     107                 :         {139,13,8147}, {116,13,8148}, {140,13,8149}, {92,13,8150}, 
     108                 :         {96,13,8151}, {157,13,8152}, {153,13,8153}, {97,13,8154}, 
     109                 :         {94,13,8155}, {93,13,8156}, {117,13,8157}, {156,13,8158}, 
     110                 :         {155,13,8159}, {95,13,8160}, {118,13,8161}, {143,13,8162}, 
     111                 :         {151,13,8163}, {142,13,8164}, {104,13,8165}, {100,13,8166}, 
     112                 :         {148,13,8167}, {144,13,8168}, {154,13,8169}, {115,13,8170}, 
     113                 :         {113,13,8171}, {98,13,8172}, {146,13,8173}, {112,13,8174}, 
     114                 :         {145,13,8175}, {149,13,8176}, {141,13,8177}, {150,13,8178}, 
     115                 :         {103,13,8179}, {147,13,8180}, {99,13,8181}, {108,13,8182}, 
     116                 :         {101,13,8183}, {114,13,8184}, {105,13,8185}, {102,13,8186}, 
     117                 :         {107,13,8187}, {109,13,8188}, {110,13,8189}, {111,13,8190}, 
     118                 :         {106,13,8191}, {0,0,8192}};
     119                 : 
     120                 : static const int table3[] = {0x20, 0x2f, 0x44, 0x71, 0x95, 0x101};
     121                 : 
     122              32 : STATIC int compress_chunk(unsigned char *inbuf, int inlen, unsigned char *outbuf, int outbuflen) {
     123              32 :     int next, m=0, j, outlen=0;
     124              32 :     unsigned reg=0;
     125                 : 
     126              32 :     next = *inbuf++;
     127              32 :     inlen--;
     128          541262 :     while(next>=0) {
     129                 :   /* Find index of input byte in table2 and put it in j */
     130          541198 :   j=0;
     131          541198 :   while(next != table2[j][0]) j++; 
     132                 : 
     133          541198 :   if(inlen) {
     134          541134 :       next = *inbuf++;
     135          541134 :       inlen--;
     136                 :   } else { 
     137              64 :       if(next == 0x100)
     138              32 :     next = -1;
     139                 :       else 
     140              32 :     next = 0x100;
     141                 :   } 
     142          541198 :   reg = (reg << table2[j][1]) | (table2[j][2] >> (13-table2[j][1]));
     143          541198 :   m += table2[j][1];
     144                 : 
     145         1434428 :   while(m>=8) {
     146          352032 :       if(outlen>=outbuflen) return -1;
     147          352032 :       *outbuf++ = (unsigned char)((reg>>(m-8)) & 0xff);
     148          352032 :       outlen++;
     149          352032 :       m-=8;
     150                 :   }
     151                 :     }
     152              32 :     if(outlen>=outbuflen) return -1;
     153              32 :     *outbuf++ = (unsigned char)((reg << (8-m)) & 0xff);
     154                 : 
     155              32 :     return outlen+1;
     156                 : }
     157                 : 
     158                 : 
     159             192 : STATIC int uncompress_chunk(unsigned char *inbuf, int inlen, unsigned char *outbuf, int outbuflen) {
     160             192 :     int i,j,k,m=0, outlen=0;
     161                 :     unsigned reg, newdata;
     162                 :     
     163             192 :     if (inlen < 4)
     164               0 :         return -1;
     165                 : 
     166             192 :     reg = *(inbuf+3) | (*(inbuf+2)<<8) | (*(inbuf+1)<<16) | (*(inbuf+0)<<24);
     167             192 :     inbuf+=4; inlen-=4;
     168                 :     
     169             192 :     newdata = (reg>>19)&0x1fff;
     170                 : 
     171                 :     while(1) {
     172         2579892 :   j = newdata >> 5;
     173                 :   
     174         2579892 :   if(table1[j] == 0xff) {
     175          114604 :       i=1;
     176          114604 :       while((int)newdata >= table2[table3[i]][2]) i++;
     177                 : 
     178          114604 :       j=table3[i-1];
     179                 : 
     180          114604 :             k = j + ((newdata-table2[j][2]) >> (13-table2[j][1]));
     181                 :       
     182          114604 :       if(table2[k][0] == 0x100) 
     183                 :     break;
     184                 :       else {
     185          114412 :     if(outlen>=outbuflen) return -1;
     186          114412 :     *outbuf++ = (unsigned char)table2[k][0];
     187          114412 :     outlen++;
     188                 :       }
     189                 :   } else {
     190         2465288 :       j=table1[j];
     191         2465288 :       if(outlen>=outbuflen) return -1;
     192         2465288 :       *outbuf++ = (unsigned char)table2[j][0];
     193         2465288 :       outlen++;
     194                 :   }
     195                 : 
     196         2579700 :   m += table2[j][1];
     197                 :   
     198         2579700 :   if(m>=19) {
     199          616582 :       if(m>=8) { 
     200         1929526 :     for(i=m>>3; i; i--) {
     201         1312944 :         if(inlen) {
     202         1312752 :       reg = (reg << 8) | *inbuf++;
     203         1312752 :       inlen--;
     204                 :         } else 
     205             192 :       reg = reg << 8;
     206                 :     }
     207                 :       }
     208          616582 :       m = m&7;
     209                 :   } 
     210         2579700 :   newdata = (reg >> (19-m)) & 0x1fff;
     211         2579700 :     }
     212             192 :     return outlen;
     213                 : }
     214                 : 
     215                 : /*
     216                 :   Reconstruct a new detail level with double resolution in the horizontal direction 
     217                 :   from data from the previous detail level and plus new differential data. 
     218                 : */
     219            1600 : STATIC blxdata *reconstruct_horiz(blxdata *base, blxdata *diff, unsigned rows, unsigned cols, blxdata *out) {
     220                 :     unsigned int i,j;
     221                 :     blxdata tmp;
     222                 : 
     223                 :     /* Last column */
     224           36672 :     for(i=0; i<rows; i++)  
     225           35072 :   out[2*(cols*i+cols-1)] = diff[cols*i+cols-1] + (((short)(base[cols*i+cols-2]-base[cols*i+cols-1]-1))>>2);
     226                 : 
     227                 :     /* Intermediate columns */
     228           36672 :     for(i=0; i<rows; i++)  
     229         1419008 :   for(j=cols-2; j>0; j--)
     230         1383936 :       out[2*(cols*i+j)] = diff[cols*i+j] + (((short)(base[cols*i+j] + 2*(base[cols*i+j-1]-out[2*(cols*i+j+1)])-3*base[cols*i+j+1]+1))>>3);
     231                 :     
     232                 :     /* First column */
     233           36672 :     for(i=0; i<rows; i++)  
     234           35072 :   out[2*cols*i] = diff[cols*i] + (((short)(base[cols*i]-base[cols*i+1]+1))>>2);
     235                 :   
     236           36672 :     for(i=0; i<rows; i++)
     237         1489152 :   for(j=0; j<cols; j++) {
     238         1454080 :       tmp=base[cols*i+j]+(((short)(out[2*(cols*i+j)]+1))>>1);
     239         1454080 :       out[2*cols*i+2*j+1] = tmp-out[2*(cols*i+j)];
     240         1454080 :       out[2*cols*i+2*j] = tmp;
     241                 :   } 
     242                 : 
     243                 : 
     244            1600 :     return out;
     245                 : }
     246                 : 
     247                 : 
     248                 : 
     249                 : /*
     250                 :   Reconstruct a new detail level with double resolution in the vertical direction 
     251                 :   from data from the previous detail level and plus new differential data. 
     252                 : */
     253             800 : STATIC blxdata *reconstruct_vert(blxdata *base, blxdata *diff, unsigned rows, unsigned cols, blxdata *out) {
     254                 :     unsigned int i,j;
     255                 :     blxdata tmp;
     256                 :     
     257                 :     /* Last row */
     258           35872 :     for(i=0; i<cols; i++)  
     259           35072 :   out[2*cols*(rows-1)+i] = diff[cols*(rows-1)+i] + (((short)(base[cols*(rows-2)+i]-base[cols*(rows-1)+i]-1))>>2);
     260                 : 
     261                 :     /* Intermediate rows */
     262           35872 :     for(i=0; i<cols; i++)  
     263         1419008 :   for(j=rows-2; j>0; j--)
     264         1383936 :       out[2*cols*j+i] = diff[cols*j+i] + ((short)((base[cols*j+i] + 2*(base[cols*(j-1)+i]-out[2*cols*(j+1)+i])-3*base[cols*(j+1)+i]+1))>>3);
     265                 :     
     266                 :     /* First row */
     267           35872 :     for(i=0; i<cols; i++)  
     268           35072 :   out[i] = diff[i] + (((short)(base[i]-base[i+cols]+1))>>2);
     269                 :   
     270           35872 :     for(i=0; i<cols; i++)
     271         1489152 :   for(j=0; j<rows; j++) {
     272         1454080 :       tmp = base[cols*j+i]+(((short)(out[2*cols*j+i]+1))>>1);
     273         1454080 :       out[cols*(2*j+1)+i] = tmp-out[2*cols*j+i];
     274         1454080 :       out[cols*2*j+i] = tmp;
     275                 :   } 
     276             800 :     return out;
     277                 : }
     278                 : 
     279                 : /*
     280                 :   Inverse of reconstruct_horiz
     281                 :  */
     282             320 : STATIC void decimate_horiz(blxdata *in, unsigned int rows, unsigned int cols, blxdata *base, blxdata *diff) {
     283                 :     unsigned int i,j;
     284                 :     blxdata tmp;
     285                 : 
     286            8256 :     for(i=0; i<rows; i++) {
     287          357120 :   for(j=0; j<cols; j+=2) {
     288          349184 :       tmp = in[i*cols+j]-in[i*cols+j+1];
     289          349184 :       diff[i*cols/2+j/2] = tmp;
     290          349184 :       base[i*cols/2+j/2] = in[i*cols+j]-(((short)(tmp+1))>>1);
     291                 :   }
     292                 :     }
     293                 :     
     294                 :     
     295                 :     /* First column */
     296            8256 :     for(i=0; i<rows; i++) {
     297            7936 :   diff[cols/2*i] -= ((short)(base[i*cols/2]-base[i*cols/2+1]+1))>>2;
     298                 :     }
     299                 : 
     300                 :     /* Intermediate columns */
     301            8256 :     for(i=0; i<rows; i++) 
     302          341248 :   for(j=1; j<cols/2-1; j++) 
     303          333312 :       diff[cols/2*i+j] -= ((short)(base[cols/2*i+j] + 2*(base[cols/2*i+j-1]-diff[cols/2*i+j+1])-3*base[cols/2*i+j+1]+1))>>3;
     304                 :     
     305                 :     /* Last column */
     306            8256 :     for(i=0; i<rows; i++)  
     307            7936 :   diff[cols/2*i+cols/2-1] -= ((short)(base[i*cols/2+cols/2-2]-base[i*cols/2+cols/2-1]-1))>>2;
     308             320 : }
     309                 : 
     310                 : /*
     311                 :   Inverse of reconstruct_vert
     312                 :  */
     313             160 : STATIC void decimate_vert(blxdata *in, unsigned int rows, unsigned int cols, blxdata *base, blxdata *diff) {
     314                 :     unsigned int i,j;
     315                 :     blxdata tmp;
     316                 : 
     317            4128 :     for(i=0; i<rows; i+=2)
     318          353152 :   for(j=0; j<cols; j++) {
     319          349184 :       tmp = in[i*cols+j]-in[(i+1)*cols+j];
     320          349184 :       diff[i/2*cols+j] = tmp;
     321          349184 :       base[i/2*cols+j] = in[i*cols+j]-(((short)(tmp+1))>>1);
     322                 :   }
     323                 :     
     324                 :     /* First row */
     325            8096 :     for(j=0; j<cols; j++)
     326            7936 :   diff[j] -= ((short)(base[j]-base[cols+j]+1))>>2;
     327                 : 
     328                 :     
     329                 :     /* Intermediate rows */
     330            3808 :     for(i=1; i<rows/2-1; i++)  
     331          336960 :   for(j=0; j<cols; j++)
     332          333312 :       diff[cols*i+j] -= ((short)(base[cols*i+j] + 2*(base[cols*(i-1)+j]-diff[cols*(i+1)+j])-3*base[cols*(i+1)+j]+1))>>3;
     333                 :     
     334                 :     /* Last row */
     335            8096 :     for(j=0; j<cols; j++)
     336            7936 :   diff[cols*(rows/2-1)+j] -= ((short)(base[cols*(rows/2-2)+j]-base[cols*(rows/2-1)+j]-1))>>2;
     337                 :        
     338             160 : }
     339                 : 
     340           57604 : static int get_short_le(unsigned char **data) {
     341                 :     int result;
     342                 : 
     343           57604 :     result = *(*data) | (*((char *)*data+1)<<8);
     344           57604 :     *data+=2;
     345           57604 :     return result;
     346                 : }
     347                 : 
     348            9261 : static int get_short_be(unsigned char **data) {
     349                 :     int result;
     350                 : 
     351            9261 :     result = *(*data+1) | (*((char *)*data)<<8);
     352            9261 :     *data+=2;
     353            9261 :     return result; 
     354                 : }
     355                 : 
     356           17644 : static void put_short_le(short data, unsigned char **bufptr) {
     357           17644 :     *(*bufptr)++ = (unsigned char)(data & 0xff);
     358           17644 :     *(*bufptr)++ = (unsigned char)((data>>8) & 0xff);
     359           17644 : }
     360                 : 
     361            3602 : static void put_short_be(short data, unsigned char **bufptr) {
     362            3602 :     *(*bufptr)++ = (unsigned char)((data>>8) & 0xff);
     363            3602 :     *(*bufptr)++ = (unsigned char)(data & 0xff);
     364            3602 : }
     365                 : 
     366                 : 
     367             192 : static int get_unsigned_short_le(unsigned char **data) {
     368                 :     int result;
     369                 : 
     370             192 :     result = *(*data) | (*(*data+1)<<8);
     371             192 :     *data+=2;
     372             192 :     return result;
     373                 : }
     374                 : 
     375             160 : static int get_unsigned_short_be(unsigned char **data) {
     376                 :     int result;
     377                 : 
     378             160 :     result = *(*data+1) | (*(*data)<<8);
     379             160 :     *data+=2;
     380             160 :     return result; 
     381                 : }
     382                 : 
     383              64 : static void put_unsigned_short_le(unsigned short data, unsigned char **bufptr) {
     384              64 :     *(*bufptr)++ = (unsigned char)(data & 0xff);
     385              64 :     *(*bufptr)++ = (unsigned char)((data>>8) & 0xff);
     386              64 : }
     387                 : 
     388              64 : static void put_unsigned_short_be(unsigned short data, unsigned char **bufptr) {
     389              64 :     *(*bufptr)++ = (unsigned char)((data>>8) & 0xff);
     390              64 :     *(*bufptr)++ = (unsigned char)(data & 0xff);
     391              64 : }
     392                 : 
     393           22605 : static int get_short(blxcontext_t *ctx, unsigned char **data) {
     394                 : 
     395           22605 :     if(ctx->endian == LITTLEENDIAN)
     396           13354 :   return get_short_le(data);
     397                 :     else 
     398            9251 :   return get_short_be(data);
     399                 : }
     400                 : 
     401             352 : static int get_unsigned_short(blxcontext_t *ctx, unsigned char **data) {
     402                 : 
     403             352 :     if(ctx->endian == LITTLEENDIAN)
     404             192 :   return get_unsigned_short_le(data);
     405                 :     else 
     406             160 :   return get_unsigned_short_be(data);
     407                 : }
     408                 : 
     409            7204 : static void put_short(blxcontext_t *ctx, short data, unsigned char **bufptr) {
     410            7204 :     if(ctx->endian == LITTLEENDIAN)
     411            3602 :   put_short_le(data, bufptr);
     412                 :     else 
     413            3602 :   put_short_be(data, bufptr);
     414            7204 : }
     415                 : 
     416             128 : static void put_unsigned_short(blxcontext_t *ctx, unsigned short data, unsigned char **bufptr) {
     417             128 :     if(ctx->endian == LITTLEENDIAN)
     418              64 :   put_unsigned_short_le(data, bufptr);
     419                 :     else 
     420              64 :   put_unsigned_short_be(data, bufptr);
     421             128 : }
     422                 : 
     423              33 : static int get_int32(blxcontext_t *ctx, unsigned char **data) {
     424                 :     int result;
     425                 : 
     426              33 :     if(ctx->endian == LITTLEENDIAN)
     427              18 :   result = *(*data) | (*(*data+1)<<8) | (*(*data+2)<<16) | (*((char *)*data+3)<<24);
     428                 :     else 
     429              15 :   result = *(*data+3) | (*(*data+2)<<8) | (*(*data+1)<<16) | (*((char *)*data)<<24);
     430              33 :     *data+=4;
     431              33 :     return result;
     432                 : }
     433                 : 
     434              76 : static void put_int32(blxcontext_t *ctx, int data, unsigned char **bufptr) {
     435              76 :     if(ctx->endian == LITTLEENDIAN) {
     436              38 :   *(*bufptr)++ = (unsigned char)(data & 0xff);
     437              38 :   *(*bufptr)++ = (unsigned char)((data>>8) & 0xff);
     438              38 :   *(*bufptr)++ = (unsigned char)((data>>16) & 0xff);
     439              38 :   *(*bufptr)++ = (unsigned char)((data>>24) & 0xff);
     440                 :     } else {
     441              38 :   *(*bufptr)++ = (unsigned char)((data>>24) & 0xff);
     442              38 :   *(*bufptr)++ = (unsigned char)((data>>16) & 0xff);
     443              38 :   *(*bufptr)++ = (unsigned char)((data>>8) & 0xff);
     444              38 :   *(*bufptr)++ = (unsigned char)(data & 0xff);
     445                 :     }
     446              76 : }
     447                 : 
     448             176 : static int get_unsigned32(blxcontext_t *ctx, unsigned char **data) {
     449                 :     int result;
     450                 : 
     451             176 :     if(ctx->endian == LITTLEENDIAN)
     452              96 :   result = *(*data) | (*(*data+1)<<8) | (*(*data+2)<<16) | (*(*data+3)<<24);
     453                 :     else 
     454              80 :   result = *(*data+3) | (*(*data+2)<<8) | (*(*data+1)<<16) | (*(*data)<<24);
     455             176 :     *data+=4;
     456             176 :     return result;
     457                 : }
     458                 : 
     459                 : /* Check native endian order */
     460             120 : int is_big_endian(void)
     461                 : {
     462             120 :   short int word = 0x0001;
     463             120 :   char *byte = (char *) &word;
     464             120 :   return (byte[0] ? 0:1);
     465                 : }
     466              28 : double doubleSWAP(double df)
     467                 : {
     468                 :   union
     469                 :   {
     470                 :     double df;
     471                 :     unsigned char b[8];
     472                 :   } dat1, dat2;
     473                 : 
     474              28 :   dat1.df = df;
     475              28 :   dat2.b[0] = dat1.b[7];
     476              28 :   dat2.b[1] = dat1.b[6];
     477              28 :   dat2.b[2] = dat1.b[5];
     478              28 :   dat2.b[3] = dat1.b[4];
     479              28 :   dat2.b[4] = dat1.b[3];
     480              28 :   dat2.b[5] = dat1.b[2];
     481              28 :   dat2.b[6] = dat1.b[1];
     482              28 :   dat2.b[7] = dat1.b[0];
     483              28 :   return dat2.df;
     484                 : }
     485                 : 
     486              44 : static double get_double(blxcontext_t *ctx, unsigned char **data) {
     487                 :     double result;
     488              44 :     memcpy(&result, *data, sizeof(double));
     489             132 :     if((is_big_endian() && ctx->endian == LITTLEENDIAN) ||
     490              88 :        (!is_big_endian() && ctx->endian == BIGENDIAN))
     491              20 :   result = doubleSWAP(result);
     492                 : 
     493              44 :     *data+=sizeof(double);
     494                 : 
     495              44 :     return result;
     496                 : }
     497                 : 
     498              16 : static void put_double(blxcontext_t *ctx, double data, unsigned char **bufptr) {
     499              48 :     if((is_big_endian() && ctx->endian == LITTLEENDIAN) ||
     500              32 :        (!is_big_endian() && ctx->endian == BIGENDIAN))
     501               8 :   data = doubleSWAP(data);
     502              16 :     memcpy(*bufptr, &data, sizeof(double));
     503              16 :     *bufptr+=sizeof(double);
     504              16 : }
     505                 : 
     506              64 : static void put_cellindex_entry(blxcontext_t *ctx, struct cellindex_s *ci, unsigned char **buffer) {
     507              64 :     put_int32(ctx, (int)ci->offset, buffer);
     508              64 :     put_unsigned_short(ctx, (unsigned short)ci->datasize, buffer);
     509              64 :     put_unsigned_short(ctx, (unsigned short)ci->compdatasize, buffer);
     510              64 : }
     511                 :      
     512                 : /* Transpose matrix in-place */
     513             728 : static void transpose(blxdata *data, int rows, int cols) {
     514                 :     int i,j;
     515                 :     blxdata tmp;
     516                 : 
     517           23448 :     for(i=0; i<rows; i++)  
     518          532320 :   for(j=i+1; j<cols; j++) {
     519          509600 :       tmp=data[i*cols+j];
     520          509600 :       data[i*cols+j]=data[j*cols+i];
     521          509600 :       data[j*cols+i]=tmp;
     522                 :   }
     523             728 : }
     524                 : 
     525                 : struct lutentry_s {
     526                 :     blxdata value;
     527                 :     int frequency;
     528                 : };  
     529           66234 : int lutcmp(const void *aa, const void *bb) {
     530           66234 :     const struct lutentry_s *a=aa, *b=bb;
     531                 : 
     532           66234 :     return b->frequency - a->frequency;
     533                 : }
     534                 : 
     535                 : 
     536              32 : int blx_encode_celldata(blxcontext_t *ctx, blxdata *indata, int side, unsigned char *outbuf, int outbufsize) {
     537              32 :     unsigned char *p=outbuf, *tmpdata, *coutstart, *cout=NULL;
     538                 :     int level, cn, coutsize, zeros;
     539              32 :     blxdata *vdec=NULL, *vdiff=NULL, *c[4], *tc1, *clut, *indata_scaled;
     540                 : 
     541                 :     struct lutentry_s lut[256];
     542              32 :     int lutsize=0;
     543                 : 
     544                 :     int i,j;
     545                 :         
     546              32 :     *p++ = (unsigned char)(side/32-4); /* Resolution */
     547                 :     
     548                 :     /* Allocated memory for buffers */
     549              32 :     indata_scaled = BLXmalloc(sizeof(blxdata)*side*side);
     550              32 :     vdec = BLXmalloc(sizeof(blxdata)*side*side/2);
     551              32 :     vdiff = BLXmalloc(sizeof(blxdata)*side*side/2);
     552             160 :     for(cn=0; cn<4; cn++) 
     553             128 :   c[cn] = BLXmalloc(sizeof(blxdata)*side*side/4);
     554              32 :     tc1 = BLXmalloc(sizeof(blxdata)*side*side/4);
     555              32 :     tmpdata = BLXmalloc(5*4*side*side/4); 
     556                 : 
     557                 :     /* Scale indata and process undefined values*/
     558          524320 :     for(i=0; i<side*side; i++) {
     559          524288 :   if((indata[i] == BLX_UNDEF) && ctx->fillundef)
     560               0 :         indata[i] = (blxdata)ctx->fillundefval;
     561          524288 :       indata_scaled[i] = (blxdata)(indata[i] / ctx->zscale);
     562                 :     }
     563                 : 
     564              32 :     indata = indata_scaled;
     565                 :     
     566              32 :     cout = tmpdata;
     567                 : 
     568             192 :     for(level=0; level < 5; level++) {
     569             160 :   if(ctx->debug) {
     570               0 :       BLXdebug1("\nlevel=%d\n", level);
     571                 :   }
     572             160 :   decimate_vert(indata, side, side, vdec, vdiff);
     573             160 :   decimate_horiz(vdec, side/2, side, c[0], c[1]);
     574             160 :   decimate_horiz(vdiff, side/2, side, c[2], c[3]);
     575                 :   
     576                 :   /* For some reason the matrix is transposed if the lut is used for vdec_hdiff */
     577            4128 :   for(i=0; i<side/2; i++)  
     578          178560 :       for(j=0; j<side/2; j++) {
     579          174592 :     tc1[j*side/2+i] = c[1][i*side/2+j];
     580          174592 :     tc1[i*side/2+j] = c[1][j*side/2+i];
     581                 :       }
     582                 :   
     583             640 :   for(cn=1; cn<4; cn++) {
     584                 :       /* Use the possibly transposed version of c when building lut */
     585             480 :       if(cn==1)
     586             160 :     clut=tc1;
     587                 :       else
     588             320 :     clut=c[cn];
     589                 : 
     590             480 :       lutsize=0;
     591             480 :       coutstart = cout;
     592          524256 :       for(i=0; i<side*side/4; i++) {
     593                 :     /* Find element in lookup table */
     594          523776 :     for(j=0; (j<lutsize) && (lut[j].value != clut[i]); j++);
     595                 :     
     596          523776 :     if(clut[i] != 0) {
     597          456638 :         if(j==lutsize) {  
     598           18636 :       lut[lutsize].value=clut[i]; 
     599           18636 :       lut[lutsize].frequency=1;
     600           18636 :       lutsize++;
     601           18636 :       if(lutsize >= 255) 
     602               0 :           break;
     603                 :         } else
     604          438002 :       lut[j].frequency++;
     605                 :     }
     606                 :       }
     607             480 :       if(lutsize < 255) {
     608                 :                 /* Since the Huffman table is arranged to let smaller number occupy
     609                 :        less bits after the compression, the lookup table is sorted on frequency */
     610             480 :     qsort(lut, lutsize, sizeof(struct lutentry_s), lutcmp);
     611                 :     
     612             480 :     zeros = 0;
     613          524256 :     for(i=0; i<side*side/4; i++) {
     614          523776 :         if(clut[i] == 0) 
     615           67138 :       zeros++;
     616          523776 :         if(((zeros>0) && (clut[i]!=0)) || (zeros >= 0x100-lutsize)) {
     617           48188 :       *cout++ = (unsigned char)(0x100-zeros); 
     618           48188 :       zeros=0;
     619                 :         }
     620          523776 :         if(clut[i] != 0) {
     621          456638 :       for(j=0; (j<lutsize) && (lut[j].value != clut[i]); j++);
     622          456638 :       *cout++ = (unsigned char)j;
     623                 :         }
     624                 :     }
     625             480 :     if(zeros>0) 
     626              24 :         *cout++ = (unsigned char)(0x100-zeros);
     627                 :       }
     628                 :       /* Use the lookuptable only when it pays off to do do.
     629                 :          For some reason there cannot be lookup tables in level 4.
     630                 :                Otherwise Mapsend crashes. */
     631             480 :       coutsize = cout-coutstart;
     632             784 :       if((lutsize < 255) && (coutsize+2*lutsize+1 < 2*side*side/4) && (level < 4)) {
     633             304 :     *p++ = (unsigned char)(lutsize+1);
     634           14042 :     for(j=0; j<lutsize; j++) 
     635           13738 :         put_short_le(lut[j].value, &p);
     636             304 :     put_short_le((short)coutsize, &p);
     637                 : 
     638             304 :     if(ctx->debug) {
     639               0 :         BLXdebug2("n=%d dlen=%d\n", lutsize+1, coutsize);
     640               0 :         BLXdebug0("lut={");
     641               0 :         for(i=0; i<lutsize; i++) 
     642               0 :       BLXdebug1("%d, ",lut[i].value);
     643               0 :         BLXdebug0("}\n");
     644                 :     }
     645                 :       } else {
     646             176 :     *p++=0;
     647             176 :     cout = coutstart;
     648            6832 :     for(i=0; i<side*side/4; i++)
     649            6656 :         put_short(ctx, c[cn][i], &cout);
     650                 :       }
     651                 :   }
     652                 : 
     653             160 :   side >>= 1;
     654             160 :   indata = c[0];
     655                 :     }
     656                 : 
     657              32 :     memcpy(p, tmpdata, cout-tmpdata);
     658              32 :     p += cout-tmpdata;
     659                 : 
     660             544 :     for(i=0; i<side*side; i++)
     661             512 :   put_short(ctx, indata[i], &p);
     662                 : 
     663              32 :     *p++=0;
     664                 : 
     665              32 :     BLXfree(indata_scaled);
     666              32 :     BLXfree(vdec); BLXfree(vdiff); 
     667             160 :     for(cn=0; cn<4; cn++) 
     668             128 :   BLXfree(c[cn]);
     669              32 :     BLXfree(tc1);
     670              32 :     BLXfree(tmpdata);
     671                 : 
     672              32 :     return p-outbuf;
     673                 : }
     674                 : 
     675             192 : STATIC blxdata *decode_celldata(blxcontext_t *ctx, unsigned char *inbuf, int len, int *side, blxdata *outbuf, int outbufsize, int overviewlevel) {
     676             192 :     unsigned char *inptr=inbuf;
     677                 :     int resolution,div,level,c,n,i,j,dpos,v,tmp,a,value,index,step,cellsize;
     678                 :     int baseside[12];
     679                 :     blxdata *base, *diff;
     680                 :     struct component_s linfo[MAXLEVELS][MAXCOMPONENTS];
     681                 : 
     682             192 :     if (len < 1)
     683                 :     {
     684               0 :         BLXerror0("Cell corrupt");
     685               0 :         return NULL;
     686                 :     }
     687             192 :     resolution = *inptr++;
     688             192 :     len --;
     689                 : 
     690             192 :     tmp = (resolution+4)*32;
     691            2304 :     for(div=1; div<12; div++) 
     692            2112 :   baseside[div-1] = tmp >> div;
     693                 : 
     694             192 :     if(side != NULL)
     695               0 :   *side = tmp >> overviewlevel;
     696                 : 
     697             192 :     cellsize = tmp*tmp;
     698             192 :     if (outbufsize < cellsize * (int)sizeof(blxdata))
     699                 :     {
     700               0 :         BLXerror0("Cell will not fit in output buffer\n");
     701               0 :         return NULL;
     702                 :     }
     703                 : 
     704             192 :     if(outbuf == NULL) {
     705               0 :   BLXerror0("outbuf is NULL");
     706               0 :   return NULL;
     707                 :     }
     708                 : 
     709             192 :     if(ctx->debug) {
     710               0 :   BLXdebug0("==============================\n");
     711                 :     }
     712                 :     
     713             192 :     base = BLXmalloc(2 * baseside[0] * baseside[0] * sizeof(blxdata));
     714             192 :     diff = BLXmalloc(2 * baseside[0] * baseside[0] * sizeof(blxdata));
     715             192 :     if (base == NULL || diff == NULL)
     716                 :     {
     717               0 :         BLXerror0("Not enough memory\n");
     718               0 :         outbuf = NULL;
     719               0 :         goto error;
     720                 :     }
     721                 : 
     722                 :     /* Clear level info structure */
     723             192 :     memset(linfo, 0, sizeof(linfo));
     724                 : 
     725            1152 :     for(level=0; level < 5; level++) {
     726            3840 :   for(c=1; c < 4; c++) {
     727            2880 :             if (len < 1)
     728                 :             {
     729               0 :                 BLXerror0("Cell corrupt");
     730               0 :                 outbuf = NULL;
     731               0 :                 goto error;
     732                 :             }
     733            2880 :       n = *inptr++;
     734            2880 :             len --;
     735            2880 :       linfo[level][c].n = n;
     736            2880 :       if(n>0) {
     737            2144 :     linfo[level][c].lut = BLXmalloc(sizeof(blxdata)*(n-1)); 
     738            2144 :                 if (len < (int)sizeof(short) * n)
     739                 :                 {
     740               0 :                     BLXerror0("Cell corrupt");
     741               0 :                     outbuf = NULL;
     742               0 :                     goto error;
     743                 :                 }
     744           44228 :     for(i=0; i<n-1; i++) 
     745           42084 :         linfo[level][c].lut[i] = (blxdata)get_short_le(&inptr);
     746            2144 :     linfo[level][c].dlen = get_short_le(&inptr);
     747            2144 :                 len -= sizeof(short) * n;
     748                 :       } else {
     749             736 :     linfo[level][c].dlen = 0;
     750                 :       }
     751                 :   }   
     752                 :     }
     753                 : 
     754            1152 :     for(level=0; level < 5; level++) {
     755             960 :   if(ctx->debug) {
     756               0 :       BLXdebug1("\nlevel=%d\n", level);
     757                 :   }
     758                 : 
     759             960 :   linfo[level][0].data = BLXmalloc(baseside[level]*baseside[level]*sizeof(blxdata));
     760             960 :         if (linfo[level][0].data == NULL)
     761                 :         {
     762               0 :             BLXerror0("Not enough memory\n");
     763               0 :             outbuf = NULL;
     764               0 :             goto error;
     765                 :         }
     766                 : 
     767            3840 :   for(c=1; c < 4; c++) {
     768            2880 :       if(ctx->debug) {
     769               0 :     BLXdebug2("n=%d dlen=%d\n", linfo[level][c].n, linfo[level][c].dlen);
     770               0 :     BLXdebug0("lut={");
     771               0 :     for(i=0; i<linfo[level][c].n-1; i++) 
     772               0 :         BLXdebug1("%d, ",linfo[level][c].lut[i]);
     773               0 :     BLXdebug0("}\n");
     774                 :       }
     775                 :       
     776            2880 :       linfo[level][c].data = BLXmalloc(baseside[level]*baseside[level]*sizeof(blxdata));
     777            2880 :             if (linfo[level][c].data == NULL)
     778                 :             {
     779               0 :                 BLXerror0("Not enough memory\n");
     780               0 :                 outbuf = NULL;
     781               0 :                 goto error;
     782                 :             }
     783                 : 
     784            2880 :       if(linfo[level][c].n == 0) {
     785             736 :                 if (len < (int)sizeof(short) * baseside[level]*baseside[level])
     786                 :                 {
     787               0 :                     BLXerror0("Cell corrupt");
     788               0 :                     outbuf = NULL;
     789               0 :                     goto error;
     790                 :                 } 
     791           20192 :     for(i=0; i<baseside[level]*baseside[level]; i++)
     792           19456 :         linfo[level][c].data[i] = (blxdata)get_short(ctx, &inptr);
     793             736 :                 len -= sizeof(short) * baseside[level]*baseside[level];
     794                 :       } else {
     795            2144 :     dpos = 0;
     796            2144 :                 if (len < linfo[level][c].dlen)
     797                 :                 {
     798               0 :                     BLXerror0("Cell corrupt");
     799               0 :                     outbuf = NULL;
     800               0 :                     goto error;
     801                 :                 }
     802         2445068 :     for(i=0; i<linfo[level][c].dlen; i++) {
     803         2442924 :         v = *inptr++;
     804         2442924 :         if(v >= linfo[level][c].n-1) {
     805          549452 :                         if(dpos + 256-v > baseside[level]*baseside[level]) {
     806               0 :                             BLXerror0("Cell corrupt\n");
     807               0 :                             outbuf = NULL;
     808               0 :                             goto error;
     809                 :                         }
     810         1779180 :       for(j=0; j<256-v; j++)
     811         1229728 :           linfo[level][c].data[dpos++] = 0;
     812                 :         }
     813                 :                     else
     814                 :                     {
     815         1893472 :                         if(dpos + 1 > baseside[level]*baseside[level]) {
     816               0 :                             BLXerror0("Cell corrupt\n");
     817               0 :                             outbuf = NULL;
     818               0 :                             goto error;
     819                 :                         }
     820         1893472 :       linfo[level][c].data[dpos++]=linfo[level][c].lut[v];
     821                 :                     }
     822                 :     }
     823            2144 :                 len -= linfo[level][c].dlen;  
     824            2144 :     if(c==1)
     825             728 :         transpose(linfo[level][c].data, baseside[level], baseside[level]);  
     826                 :       }
     827                 :       if(0 && ctx->debug) {
     828                 :     BLXdebug1("baseside:%d\n",baseside[level]);
     829                 :     BLXdebug0("data={");
     830                 :     for(i=0; i<baseside[level]*baseside[level]; i++) 
     831                 :         BLXdebug1("%d, ",linfo[level][c].data[i]);
     832                 :     BLXdebug0("}\n");
     833                 :       }
     834                 : 
     835                 : 
     836                 :   }
     837                 : 
     838                 :     }
     839                 :     
     840             192 :     if (len < (int)sizeof(short) * baseside[4]*baseside[4])
     841                 :     {
     842               0 :         BLXerror0("Cell corrupt");
     843               0 :         outbuf = NULL;
     844               0 :         goto error;
     845                 :     }
     846            3264 :     for(i=0; i<baseside[4]*baseside[4]; i++)
     847            3072 :   linfo[4][0].data[i] = (blxdata)get_short(ctx, &inptr);
     848             192 :     len -=sizeof(short) * baseside[4]*baseside[4];
     849                 :     
     850             992 :     for(level=4; level >= overviewlevel; level--) {
     851             800 :   if(ctx->debug) {
     852               0 :       BLXdebug1("baseside:%d\n",baseside[level]);
     853               0 :       BLXdebug0("inbase={");
     854               0 :       for(i=0; i<baseside[level]*baseside[level]; i++) 
     855               0 :     BLXdebug1("%d, ",linfo[level][0].data[i]);
     856               0 :       BLXdebug0("}\n");
     857               0 :       BLXdebug0("indiff={");
     858               0 :       for(i=0; i<baseside[level]*baseside[level]; i++) 
     859               0 :     BLXdebug1("%d, ",linfo[level][1].data[i]);
     860               0 :       BLXdebug0("}\n");
     861                 :   }
     862                 : 
     863                 : 
     864             800 :   reconstruct_horiz(linfo[level][0].data, linfo[level][1].data, baseside[level], baseside[level], base);
     865             800 :   if(ctx->debug) {
     866               0 :       BLXdebug0("base={");
     867               0 :       for(i=0; i<baseside[level]*baseside[level]; i++) 
     868               0 :     BLXdebug1("%d, ",base[i]);
     869               0 :       BLXdebug0("}\n");
     870                 :   }
     871                 : 
     872             800 :   reconstruct_horiz(linfo[level][2].data, linfo[level][3].data, baseside[level], baseside[level], diff);  
     873             800 :   if(ctx->debug) {
     874               0 :       BLXdebug0("diff={");
     875               0 :       for(i=0; i<baseside[level]*baseside[level]; i++) 
     876               0 :     BLXdebug1("%d, ",diff[i]);
     877               0 :       BLXdebug0("}\n");
     878                 :   }
     879             800 :   if(level>overviewlevel) 
     880             608 :       reconstruct_vert(base, diff, baseside[level], 2*baseside[level], linfo[level-1][0].data);
     881                 :   else  
     882             192 :       reconstruct_vert(base, diff, baseside[level], 2*baseside[level], outbuf);
     883                 :     }    
     884                 : 
     885             192 :     if(overviewlevel == 0) {
     886             128 :         if (len < 1)
     887                 :         {
     888               0 :             BLXerror0("Cell corrupt");
     889               0 :             outbuf = NULL;
     890               0 :             goto error;
     891                 :         }
     892             128 :   a = *((char *)inptr++);
     893             128 :         len --;
     894             128 :   index=0;
     895             256 :   while(len >= 3) {
     896               0 :       step = inptr[0] | (inptr[1]<<8); inptr+=2;
     897               0 :       value = *((char *)inptr++);
     898               0 :             len -= 3;
     899                 : 
     900               0 :       index += step;
     901                 : 
     902               0 :       if(value & 1) 
     903               0 :     value = (value-1)/2-a;
     904                 :       else  
     905               0 :     value = value/2+a;
     906                 : 
     907               0 :       if(index>=cellsize) {
     908               0 :     BLXerror0("Cell data corrupt\n");
     909               0 :     outbuf = NULL;
     910               0 :     goto error;
     911                 :       }
     912                 : 
     913               0 :       outbuf[index] = outbuf[index] + (blxdata)value;
     914                 :   }
     915                 : 
     916             128 :         if (len != 0)
     917               0 :             BLXdebug1("remaining len=%d", len);
     918                 :     }
     919                 :     else
     920                 :     {
     921              64 :         if (len != 1)
     922               0 :             BLXdebug1("remaining len=%d", len);
     923                 :     }
     924                 : 
     925                 :     /* Scale data */
     926         3145920 :     for(i=0; i<cellsize; i++)
     927         3145728 :   outbuf[i] = outbuf[i] * (blxdata)ctx->zscale;
     928                 : 
     929                 : 
     930                 :  error:
     931             192 :     if (base != NULL)
     932             192 :          BLXfree(base);
     933             192 :     if (diff != NULL)
     934             192 :          BLXfree(diff);
     935                 : 
     936                 :     /* Free allocated memory */
     937            1152 :     for(level=4; level >= 0; level--) 
     938            4800 :   for(c=0; c<4; c++) {
     939            3840 :       if(linfo[level][c].lut)
     940            2144 :     BLXfree(linfo[level][c].lut);
     941            3840 :       if(linfo[level][c].data)
     942            3840 :     BLXfree(linfo[level][c].data);
     943                 :   }
     944                 : 
     945             192 :     return outbuf;
     946                 : }
     947                 : 
     948              15 : blxcontext_t *blx_create_context() {
     949                 :     blxcontext_t *c;
     950                 :     
     951              15 :     c = BLXmalloc(sizeof(blxcontext_t));
     952                 :     
     953              15 :     memset(c,0,sizeof(blxcontext_t));
     954                 :     
     955              15 :     c->cell_ysize = c->cell_xsize = 128;
     956                 :     
     957              15 :     c->minval = 32767;
     958              15 :     c->maxval = -32768;
     959                 : 
     960              15 :     c->debug = 0;
     961                 : 
     962              15 :     c->zscale = 1;
     963                 : 
     964              15 :     c->fillundef = 1;  
     965              15 :     c->fillundefval = 0;
     966                 : 
     967              15 :     return c;
     968                 : }
     969                 : 
     970              15 : void blx_free_context(blxcontext_t *ctx) {
     971              15 :     if(ctx->cellindex) 
     972              13 :   BLXfree(ctx->cellindex);
     973                 : 
     974              15 :     BLXfree(ctx);
     975              15 : }
     976                 : 
     977               0 : void blxprintinfo(blxcontext_t *ctx) {
     978               0 :     BLXnotice2("Lat: %f Lon: %f\n", ctx->lat, ctx->lon);
     979               0 :     BLXnotice2("Pixelsize: Lat: %f Lon: %f\n", 3600*ctx->pixelsize_lat, 3600*ctx->pixelsize_lon);
     980               0 :     BLXnotice2("Size %dx%d\n", ctx->xsize, ctx->ysize);
     981               0 :     BLXnotice2("Cell size %dx%d\n", ctx->cell_xsize, ctx->cell_ysize);
     982               0 :     BLXnotice2("Cell grid %dx%d\n", ctx->cell_cols, ctx->cell_rows);
     983               0 :     BLXnotice1("Ysize scale factor: %d\n", ctx->zscale);
     984               0 :     BLXnotice1("Max Ysize: %d\n", ctx->zscale * ctx->maxval);
     985               0 :     BLXnotice1("Min Ysize: %d\n", ctx->zscale * ctx->minval);
     986               0 :     BLXnotice1("Max chunksize: %d\n", ctx->maxchunksize);
     987               0 : }
     988                 : 
     989             259 : int blx_checkheader(char *header) {
     990             259 :     short *signature=(short *)header;
     991                 : 
     992             517 :     return ((signature[0]==0x4) && (signature[1]==0x66)) ||
     993             258 :   ((signature[0]==0x400) && (signature[1]==0x6600));
     994                 : }
     995                 : 
     996               4 : void blx_generate_header(blxcontext_t *ctx, unsigned char *header) {
     997               4 :     unsigned char *hptr = header;
     998                 :     
     999               4 :     memset(header, 0, 102);
    1000                 : 
    1001                 :     /* Write signature */
    1002               4 :     put_short(ctx, 0x4, &hptr); // 0
    1003               4 :     put_short(ctx, 0x66, &hptr); // 2
    1004                 : 
    1005               4 :     put_int32(ctx, ctx->cell_xsize*ctx->cell_cols, &hptr); // 4
    1006               4 :     put_int32(ctx, ctx->cell_ysize*ctx->cell_rows, &hptr); // 8
    1007                 : 
    1008               4 :     put_short(ctx, (short)ctx->cell_xsize, &hptr); // 12
    1009               4 :     put_short(ctx, (short)ctx->cell_ysize, &hptr); // 14
    1010                 : 
    1011               4 :     put_short(ctx, (short)ctx->cell_cols, &hptr); // 16
    1012               4 :     put_short(ctx, (short)ctx->cell_rows, &hptr); // 18
    1013                 : 
    1014               4 :     put_double(ctx, ctx->lon, &hptr); // 20
    1015               4 :     put_double(ctx, -ctx->lat, &hptr); // 28
    1016                 : 
    1017               4 :     put_double(ctx, ctx->pixelsize_lon, &hptr);  // 36 
    1018               4 :     put_double(ctx, -ctx->pixelsize_lat, &hptr); // 44
    1019                 : 
    1020               4 :     put_short(ctx, (short)ctx->minval, &hptr); // 52
    1021               4 :     put_short(ctx, (short)ctx->maxval, &hptr); // 54
    1022               4 :     put_short(ctx, (short)ctx->zscale, &hptr); // 56
    1023               4 :     put_int32(ctx, ctx->maxchunksize, &hptr); // 58
    1024                 :     // 62
    1025               4 : }
    1026                 : 
    1027              32 : int blx_writecell(blxcontext_t *ctx, blxdata *cell, int cellrow, int cellcol) {
    1028              32 :     unsigned char *uncompbuf=NULL,*outbuf=NULL;
    1029                 :     int bufsize, uncompsize, compsize;
    1030              32 :     int status=0;
    1031                 :     int i,allundef;
    1032                 : 
    1033                 :     /* Calculate statistics and find out if all elements have undefined values */
    1034              32 :     allundef=1;
    1035          524320 :     for(i=0; i < ctx->cell_xsize*ctx->cell_ysize; i++) {
    1036          524288 :   if(cell[i] > ctx->maxval)
    1037             224 :       ctx->maxval = cell[i];
    1038          524288 :   if(cell[i] < ctx->minval)
    1039              14 :       ctx->minval = cell[i];
    1040          524288 :   if(cell[i]!=BLX_UNDEF)
    1041          524288 :       allundef=0;
    1042                 :     }   
    1043                 : 
    1044              32 :     if(allundef)
    1045               0 :   return status;
    1046                 : 
    1047              32 :     if(ctx->debug)
    1048               0 :   BLXdebug2("Writing cell (%d,%d)\n",cellrow, cellcol);
    1049                 : 
    1050              32 :     if(!ctx->open) {
    1051               0 :   status=-3;
    1052               0 :   goto error;
    1053                 :     }
    1054                 : 
    1055              32 :     if((cellrow >= ctx->cell_rows) || (cellcol >= ctx->cell_cols)) {
    1056               0 :   status=-2;
    1057               0 :   goto error;
    1058                 :     }
    1059                 :     
    1060              32 :     bufsize = sizeof(blxdata)*ctx->cell_xsize*ctx->cell_ysize+1024;
    1061              32 :     uncompbuf = BLXmalloc(bufsize);
    1062              32 :     outbuf = BLXmalloc(bufsize);
    1063                 :     
    1064              32 :     uncompsize = blx_encode_celldata(ctx, cell, ctx->cell_xsize, uncompbuf, bufsize);
    1065              32 :     compsize = compress_chunk(uncompbuf, uncompsize, outbuf, bufsize);
    1066              32 :     if (compsize < 0)
    1067                 :     {
    1068               0 :         BLXerror0("Couldn't compress chunk");
    1069               0 :         status = -1;
    1070               0 :         goto error;
    1071                 :     }
    1072                 : 
    1073              32 :     if(uncompsize > ctx->maxchunksize)
    1074              12 :   ctx->maxchunksize = uncompsize;
    1075                 :     
    1076              32 :     ctx->cellindex[cellrow*ctx->cell_cols + cellcol].offset = BLXftell(ctx->fh);
    1077              32 :     ctx->cellindex[cellrow*ctx->cell_cols + cellcol].datasize = uncompsize;
    1078              32 :     ctx->cellindex[cellrow*ctx->cell_cols + cellcol].compdatasize = compsize;
    1079                 :     
    1080              32 :     if((int)BLXfwrite(outbuf, 1, compsize, ctx->fh) != compsize) {
    1081               0 :   status=-1;
    1082                 :   goto error;
    1083                 :     }
    1084                 :     
    1085                 :  error:
    1086              32 :     if(uncompbuf) 
    1087              32 :   BLXfree(uncompbuf);
    1088              32 :     if(outbuf)
    1089              32 :   BLXfree(outbuf);
    1090              32 :     return status;
    1091                 : }
    1092                 : 
    1093              15 : int blxopen(blxcontext_t *ctx, const char *filename, const char *rw) {
    1094                 :     unsigned char header[102],*hptr;
    1095                 :     int signature[2];
    1096                 :     int i,j;
    1097                 :     struct cellindex_s *ci;
    1098                 : 
    1099              26 :     if(!strcmp(rw, "r") || !strcmp(rw, "rb"))
    1100              11 :   ctx->write=0;
    1101               4 :     else if(!strcmp(rw,"w") || !strcmp(rw, "wb"))
    1102               4 :   ctx->write=1;
    1103                 :     else
    1104                 :   goto error;
    1105                 : 
    1106              15 :     ctx->fh = BLXfopen(filename, rw);
    1107                 : 
    1108              15 :     if(ctx->fh == NULL)
    1109               2 :   goto error;
    1110                 : 
    1111              13 :     hptr = header;
    1112              13 :     if(ctx->write) {
    1113               2 :   blx_generate_header(ctx, header);
    1114                 :   
    1115               2 :   if(BLXfwrite(header, 1, 102, ctx->fh) != 102)
    1116               0 :       goto error;
    1117                 : 
    1118               2 :   ctx->cellindex = BLXmalloc(sizeof(struct cellindex_s) * ctx->cell_rows * ctx->cell_cols);
    1119               2 :   if(ctx->cellindex == NULL) {
    1120               0 :       goto error;
    1121                 :   }
    1122               2 :   memset(ctx->cellindex, 0, sizeof(struct cellindex_s) * ctx->cell_rows * ctx->cell_cols);
    1123                 :   
    1124                 :   /* Write the empty cell index (this will be overwritten when we have actual data)*/
    1125              10 :   for(i=0;i<ctx->cell_rows;i++)
    1126              40 :       for(j=0;j<ctx->cell_cols;j++) {
    1127              32 :     hptr = header;
    1128              32 :     put_cellindex_entry(ctx, ctx->cellindex+i*ctx->cell_cols+j, &hptr);
    1129              32 :     if((int)BLXfwrite(header, 1, hptr-header, ctx->fh) != (int)(hptr-header))
    1130               0 :         goto error;
    1131                 :       }
    1132                 : 
    1133                 :     } else {
    1134                 :   /* Read header */
    1135              11 :   if(BLXfread(header, 1, 102, ctx->fh) != 102)
    1136               0 :       goto error;
    1137                 :     
    1138              11 :   signature[0] = get_short_le(&hptr);
    1139              11 :   signature[1] = get_short_le(&hptr);
    1140                 : 
    1141                 :   /* Determine if the endianess of the BLX file */
    1142              17 :   if((signature[0] == 0x4) && (signature[1] == 0x66)) 
    1143               6 :       ctx->endian = LITTLEENDIAN;
    1144                 :   else {  
    1145               5 :       hptr = header;
    1146               5 :       signature[0] = get_short_be(&hptr);
    1147               5 :       signature[1] = get_short_be(&hptr);
    1148               5 :       if((signature[0] == 0x4) && (signature[1] == 0x66)) 
    1149               5 :     ctx->endian = BIGENDIAN;
    1150                 :       else 
    1151                 :     goto error;
    1152                 :   }
    1153                 : 
    1154              11 :   ctx->xsize = get_int32(ctx, &hptr);
    1155              11 :   ctx->ysize = get_int32(ctx, &hptr);
    1156              11 :         if (ctx->xsize <= 0 || ctx->ysize <= 0)
    1157                 :         {
    1158               0 :             BLXerror0("Invalid raster size");
    1159               0 :             goto error;
    1160                 :         }
    1161                 : 
    1162              11 :   ctx->cell_xsize = get_short(ctx, &hptr);
    1163              11 :   ctx->cell_ysize = get_short(ctx, &hptr);
    1164              22 :         if (ctx->cell_xsize <= 0 ||
    1165              11 :             ctx->cell_ysize <= 0)
    1166                 :         {
    1167               0 :             BLXerror0("Invalid cell size");
    1168               0 :             goto error;
    1169                 :         }
    1170                 : 
    1171              11 :   ctx->cell_cols = get_short(ctx, &hptr);
    1172              11 :   ctx->cell_rows = get_short(ctx, &hptr);
    1173              33 :         if (ctx->cell_cols <= 0 || ctx->cell_cols > 10000 ||
    1174              22 :             ctx->cell_rows <= 0 || ctx->cell_rows > 10000)
    1175                 :         {
    1176               0 :             BLXerror0("Invalid cell number");
    1177               0 :             goto error;
    1178                 :         }
    1179                 : 
    1180              11 :   ctx->lon = get_double(ctx, &hptr);
    1181              11 :   ctx->lat = -get_double(ctx, &hptr);
    1182                 : 
    1183              11 :   ctx->pixelsize_lon = get_double(ctx, &hptr);
    1184              11 :   ctx->pixelsize_lat = -get_double(ctx, &hptr);
    1185                 :     
    1186              11 :   ctx->minval = get_short(ctx, &hptr); 
    1187              11 :   ctx->maxval = get_short(ctx, &hptr);
    1188              11 :   ctx->zscale = get_short(ctx, &hptr);
    1189              11 :   ctx->maxchunksize = get_int32(ctx, &hptr);
    1190                 : 
    1191              11 :   ctx->cellindex = BLXmalloc(sizeof(struct cellindex_s) * ctx->cell_rows * ctx->cell_cols);
    1192              11 :   if(ctx->cellindex == NULL) {
    1193               0 :       goto error;
    1194                 :   }
    1195                 : 
    1196              55 :   for(i=0;i<ctx->cell_rows;i++)
    1197             220 :       for(j=0;j<ctx->cell_cols;j++) {
    1198                 :     /* Read cellindex entry */
    1199             176 :     if(BLXfread(header, 1, 8, ctx->fh) != 8)
    1200               0 :         goto error;
    1201             176 :     hptr=header;
    1202                 : 
    1203             176 :     ci = &ctx->cellindex[i*ctx->cell_cols + j]; 
    1204             176 :     ci->offset = get_unsigned32(ctx, &hptr);
    1205             176 :     ci->datasize = get_unsigned_short(ctx, &hptr);
    1206             176 :     ci->compdatasize = get_unsigned_short(ctx, &hptr);
    1207                 :       }
    1208                 :     }
    1209              13 :     ctx->open = 1;
    1210                 : 
    1211              13 :     return 0;
    1212                 : 
    1213                 :  error:
    1214               2 :     return -1;
    1215                 : }
    1216                 : 
    1217              13 : int blxclose(blxcontext_t *ctx) {
    1218                 :     unsigned char header[102],*hptr;
    1219              13 :     int i,j,status=0;
    1220                 : 
    1221              13 :     if(ctx->write) {
    1222                 :   /* Write updated header and cellindex */
    1223               2 :   BLXfseek(ctx->fh, 0, SEEK_SET);
    1224                 : 
    1225               2 :   blx_generate_header(ctx, header);
    1226                 :   
    1227               2 :   if(BLXfwrite(header, 1, 102, ctx->fh) != 102) {
    1228               0 :       status=-1;
    1229               0 :       goto error;
    1230                 :   }
    1231              10 :   for(i=0;i<ctx->cell_rows;i++)
    1232              40 :       for(j=0;j<ctx->cell_cols;j++) {
    1233              32 :     hptr = header;
    1234              32 :     put_cellindex_entry(ctx, ctx->cellindex+i*ctx->cell_cols+j, &hptr);
    1235              32 :     if((int)BLXfwrite(header, 1, hptr-header, ctx->fh) != (int)(hptr-header)) {
    1236               0 :         status=-1;  
    1237               0 :         break;
    1238                 :     }
    1239                 :       }
    1240                 :     }
    1241              13 :     ctx->open = 1;
    1242                 : 
    1243                 :  error: 
    1244              13 :     if(ctx->fh)
    1245              13 :   BLXfclose(ctx->fh);
    1246                 :     
    1247              13 :     return status;
    1248                 : }
    1249                 : 
    1250             192 : short *blx_readcell(blxcontext_t *ctx, int row, int col, short *buffer, int bufsize, int overviewlevel) {
    1251                 :     struct cellindex_s *ci;
    1252             192 :     unsigned char *chunk=NULL, *cchunk=NULL;
    1253             192 :     blxdata *tmpbuf=NULL;
    1254                 :     int tmpbufsize,i;
    1255             192 :     short *result=NULL;
    1256                 :     int npoints;
    1257                 :     
    1258             192 :     if((ctx==NULL) || (row >= ctx->cell_rows) || (col >= ctx->cell_cols))
    1259               0 :   return NULL;
    1260                 : 
    1261             192 :     ci = &ctx->cellindex[row*ctx->cell_cols + col];
    1262                 : 
    1263             192 :     npoints = (ctx->cell_xsize*ctx->cell_ysize)>>(2*overviewlevel) ;
    1264             192 :     if (bufsize < npoints * (int)sizeof(short))
    1265               0 :         return NULL;
    1266                 : 
    1267             192 :     if(ci->datasize == 0) {
    1268               0 :   for(i=0; i<npoints; i++)
    1269               0 :       buffer[i] = BLX_UNDEF;
    1270                 :     } else {
    1271             192 :   BLXfseek(ctx->fh, ci->offset, SEEK_SET);
    1272                 : 
    1273             192 :   chunk = BLXmalloc(ci->datasize);
    1274             192 :   cchunk = BLXmalloc(ci->compdatasize);
    1275                 : 
    1276             192 :   if((chunk == NULL) || (cchunk == NULL)) 
    1277                 :       goto error;
    1278                 :     
    1279             192 :   if(BLXfread(cchunk, 1, ci->compdatasize, ctx->fh) != ci->compdatasize)
    1280               0 :       goto error;
    1281                 :     
    1282             192 :         if((unsigned int)uncompress_chunk(cchunk, ci->compdatasize, chunk, ci->datasize) != ci->datasize)
    1283               0 :       goto error;
    1284                 : 
    1285             192 :   tmpbufsize = sizeof(blxdata)*ctx->cell_xsize*ctx->cell_ysize;
    1286             192 :   tmpbuf = BLXmalloc(tmpbufsize);
    1287             192 :         if (tmpbuf == NULL)
    1288               0 :             goto error;
    1289                 :     
    1290             192 :   if (decode_celldata(ctx, chunk, ci->datasize, NULL, tmpbuf, tmpbufsize, overviewlevel) == NULL)
    1291               0 :             goto error;
    1292                 :     
    1293         2184384 :   for(i=0; i<npoints; i++)
    1294         2184192 :       buffer[i] = tmpbuf[i];
    1295                 :     }
    1296                 : 
    1297             192 :     result = buffer;
    1298                 : 
    1299                 :  error:
    1300             192 :     if(chunk)
    1301             192 :   BLXfree(chunk);
    1302             192 :     if(cchunk)
    1303             192 :   BLXfree(cchunk);
    1304             192 :     if(tmpbuf)
    1305             192 :   BLXfree(tmpbuf);
    1306                 : 
    1307             192 :     return result;
    1308                 : }

Generated by: LCOV version 1.7