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: 2012-04-28 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              64 : STATIC int compress_chunk(unsigned char *inbuf, int inlen, unsigned char *outbuf, int outbuflen) {
     123              64 :     int next, m=0, j, outlen=0;
     124              64 :     unsigned reg=0;
     125                 : 
     126              64 :     next = *inbuf++;
     127              64 :     inlen--;
     128         1082524 :     while(next>=0) {
     129                 :   /* Find index of input byte in table2 and put it in j */
     130         1082396 :   j=0;
     131         1082396 :   while(next != table2[j][0]) j++; 
     132                 : 
     133         1082396 :   if(inlen) {
     134         1082268 :       next = *inbuf++;
     135         1082268 :       inlen--;
     136                 :   } else { 
     137             128 :       if(next == 0x100)
     138              64 :     next = -1;
     139                 :       else 
     140              64 :     next = 0x100;
     141                 :   } 
     142         1082396 :   reg = (reg << table2[j][1]) | (table2[j][2] >> (13-table2[j][1]));
     143         1082396 :   m += table2[j][1];
     144                 : 
     145         2868856 :   while(m>=8) {
     146          704064 :       if(outlen>=outbuflen) return -1;
     147          704064 :       *outbuf++ = (unsigned char)((reg>>(m-8)) & 0xff);
     148          704064 :       outlen++;
     149          704064 :       m-=8;
     150                 :   }
     151                 :     }
     152              64 :     if(outlen>=outbuflen) return -1;
     153              64 :     *outbuf++ = (unsigned char)((reg << (8-m)) & 0xff);
     154                 : 
     155              64 :     return outlen+1;
     156                 : }
     157                 : 
     158                 : 
     159             384 : STATIC int uncompress_chunk(unsigned char *inbuf, int inlen, unsigned char *outbuf, int outbuflen) {
     160             384 :     int i,j,k,m=0, outlen=0;
     161                 :     unsigned reg, newdata;
     162                 :     
     163             384 :     if (inlen < 4)
     164               0 :         return -1;
     165                 : 
     166             384 :     reg = *(inbuf+3) | (*(inbuf+2)<<8) | (*(inbuf+1)<<16) | (*(inbuf+0)<<24);
     167             384 :     inbuf+=4; inlen-=4;
     168                 :     
     169             384 :     newdata = (reg>>19)&0x1fff;
     170                 : 
     171                 :     while(1) {
     172         5159784 :   j = newdata >> 5;
     173                 :   
     174         5159784 :   if(table1[j] == 0xff) {
     175          229208 :       i=1;
     176          229208 :       while((int)newdata >= table2[table3[i]][2]) i++;
     177                 : 
     178          229208 :       j=table3[i-1];
     179                 : 
     180          229208 :             k = j + ((newdata-table2[j][2]) >> (13-table2[j][1]));
     181                 :       
     182          229208 :       if(table2[k][0] == 0x100) 
     183                 :     break;
     184                 :       else {
     185          228824 :     if(outlen>=outbuflen) return -1;
     186          228824 :     *outbuf++ = (unsigned char)table2[k][0];
     187          228824 :     outlen++;
     188                 :       }
     189                 :   } else {
     190         4930576 :       j=table1[j];
     191         4930576 :       if(outlen>=outbuflen) return -1;
     192         4930576 :       *outbuf++ = (unsigned char)table2[j][0];
     193         4930576 :       outlen++;
     194                 :   }
     195                 : 
     196         5159400 :   m += table2[j][1];
     197                 :   
     198         5159400 :   if(m>=19) {
     199         1233164 :       if(m>=8) { 
     200         3859052 :     for(i=m>>3; i; i--) {
     201         2625888 :         if(inlen) {
     202         2625504 :       reg = (reg << 8) | *inbuf++;
     203         2625504 :       inlen--;
     204                 :         } else 
     205             384 :       reg = reg << 8;
     206                 :     }
     207                 :       }
     208         1233164 :       m = m&7;
     209                 :   } 
     210         5159400 :   newdata = (reg >> (19-m)) & 0x1fff;
     211         5159400 :     }
     212             384 :     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            3200 : 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           73344 :     for(i=0; i<rows; i++)  
     225           70144 :   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           73344 :     for(i=0; i<rows; i++)  
     229         2838016 :   for(j=cols-2; j>0; j--)
     230         2767872 :       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           73344 :     for(i=0; i<rows; i++)  
     234           70144 :   out[2*cols*i] = diff[cols*i] + (((short)(base[cols*i]-base[cols*i+1]+1))>>2);
     235                 :   
     236           73344 :     for(i=0; i<rows; i++)
     237         2978304 :   for(j=0; j<cols; j++) {
     238         2908160 :       tmp=base[cols*i+j]+(((short)(out[2*(cols*i+j)]+1))>>1);
     239         2908160 :       out[2*cols*i+2*j+1] = tmp-out[2*(cols*i+j)];
     240         2908160 :       out[2*cols*i+2*j] = tmp;
     241                 :   } 
     242                 : 
     243                 : 
     244            3200 :     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            1600 : 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           71744 :     for(i=0; i<cols; i++)  
     259           70144 :   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           71744 :     for(i=0; i<cols; i++)  
     263         2838016 :   for(j=rows-2; j>0; j--)
     264         2767872 :       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           71744 :     for(i=0; i<cols; i++)  
     268           70144 :   out[i] = diff[i] + (((short)(base[i]-base[i+cols]+1))>>2);
     269                 :   
     270           71744 :     for(i=0; i<cols; i++)
     271         2978304 :   for(j=0; j<rows; j++) {
     272         2908160 :       tmp = base[cols*j+i]+(((short)(out[2*cols*j+i]+1))>>1);
     273         2908160 :       out[cols*(2*j+1)+i] = tmp-out[2*cols*j+i];
     274         2908160 :       out[cols*2*j+i] = tmp;
     275                 :   } 
     276            1600 :     return out;
     277                 : }
     278                 : 
     279                 : /*
     280                 :   Inverse of reconstruct_horiz
     281                 :  */
     282             640 : 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           16512 :     for(i=0; i<rows; i++) {
     287          714240 :   for(j=0; j<cols; j+=2) {
     288          698368 :       tmp = in[i*cols+j]-in[i*cols+j+1];
     289          698368 :       diff[i*cols/2+j/2] = tmp;
     290          698368 :       base[i*cols/2+j/2] = in[i*cols+j]-(((short)(tmp+1))>>1);
     291                 :   }
     292                 :     }
     293                 :     
     294                 :     
     295                 :     /* First column */
     296           16512 :     for(i=0; i<rows; i++) {
     297           15872 :   diff[cols/2*i] -= ((short)(base[i*cols/2]-base[i*cols/2+1]+1))>>2;
     298                 :     }
     299                 : 
     300                 :     /* Intermediate columns */
     301           16512 :     for(i=0; i<rows; i++) 
     302          682496 :   for(j=1; j<cols/2-1; j++) 
     303          666624 :       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           16512 :     for(i=0; i<rows; i++)  
     307           15872 :   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             640 : }
     309                 : 
     310                 : /*
     311                 :   Inverse of reconstruct_vert
     312                 :  */
     313             320 : 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            8256 :     for(i=0; i<rows; i+=2)
     318          706304 :   for(j=0; j<cols; j++) {
     319          698368 :       tmp = in[i*cols+j]-in[(i+1)*cols+j];
     320          698368 :       diff[i/2*cols+j] = tmp;
     321          698368 :       base[i/2*cols+j] = in[i*cols+j]-(((short)(tmp+1))>>1);
     322                 :   }
     323                 :     
     324                 :     /* First row */
     325           16192 :     for(j=0; j<cols; j++)
     326           15872 :   diff[j] -= ((short)(base[j]-base[cols+j]+1))>>2;
     327                 : 
     328                 :     
     329                 :     /* Intermediate rows */
     330            7616 :     for(i=1; i<rows/2-1; i++)  
     331          673920 :   for(j=0; j<cols; j++)
     332          666624 :       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           16192 :     for(j=0; j<cols; j++)
     336           15872 :   diff[cols*(rows/2-1)+j] -= ((short)(base[cols*(rows/2-2)+j]-base[cols*(rows/2-1)+j]-1))>>2;
     337                 :        
     338             320 : }
     339                 : 
     340          115208 : static int get_short_le(unsigned char **data) {
     341                 :     int result;
     342                 : 
     343          115208 :     result = *(*data) | (*((char *)*data+1)<<8);
     344          115208 :     *data+=2;
     345          115208 :     return result;
     346                 : }
     347                 : 
     348           18522 : static int get_short_be(unsigned char **data) {
     349                 :     int result;
     350                 : 
     351           18522 :     result = *(*data+1) | (*((char *)*data)<<8);
     352           18522 :     *data+=2;
     353           18522 :     return result; 
     354                 : }
     355                 : 
     356           35288 : static void put_short_le(short data, unsigned char **bufptr) {
     357           35288 :     *(*bufptr)++ = (unsigned char)(data & 0xff);
     358           35288 :     *(*bufptr)++ = (unsigned char)((data>>8) & 0xff);
     359           35288 : }
     360                 : 
     361            7204 : static void put_short_be(short data, unsigned char **bufptr) {
     362            7204 :     *(*bufptr)++ = (unsigned char)((data>>8) & 0xff);
     363            7204 :     *(*bufptr)++ = (unsigned char)(data & 0xff);
     364            7204 : }
     365                 : 
     366                 : 
     367             384 : static int get_unsigned_short_le(unsigned char **data) {
     368                 :     int result;
     369                 : 
     370             384 :     result = *(*data) | (*(*data+1)<<8);
     371             384 :     *data+=2;
     372             384 :     return result;
     373                 : }
     374                 : 
     375             320 : static int get_unsigned_short_be(unsigned char **data) {
     376                 :     int result;
     377                 : 
     378             320 :     result = *(*data+1) | (*(*data)<<8);
     379             320 :     *data+=2;
     380             320 :     return result; 
     381                 : }
     382                 : 
     383             128 : static void put_unsigned_short_le(unsigned short data, unsigned char **bufptr) {
     384             128 :     *(*bufptr)++ = (unsigned char)(data & 0xff);
     385             128 :     *(*bufptr)++ = (unsigned char)((data>>8) & 0xff);
     386             128 : }
     387                 : 
     388             128 : static void put_unsigned_short_be(unsigned short data, unsigned char **bufptr) {
     389             128 :     *(*bufptr)++ = (unsigned char)((data>>8) & 0xff);
     390             128 :     *(*bufptr)++ = (unsigned char)(data & 0xff);
     391             128 : }
     392                 : 
     393           45210 : static int get_short(blxcontext_t *ctx, unsigned char **data) {
     394                 : 
     395           45210 :     if(ctx->endian == LITTLEENDIAN)
     396           26708 :   return get_short_le(data);
     397                 :     else 
     398           18502 :   return get_short_be(data);
     399                 : }
     400                 : 
     401             704 : static int get_unsigned_short(blxcontext_t *ctx, unsigned char **data) {
     402                 : 
     403             704 :     if(ctx->endian == LITTLEENDIAN)
     404             384 :   return get_unsigned_short_le(data);
     405                 :     else 
     406             320 :   return get_unsigned_short_be(data);
     407                 : }
     408                 : 
     409           14408 : static void put_short(blxcontext_t *ctx, short data, unsigned char **bufptr) {
     410           14408 :     if(ctx->endian == LITTLEENDIAN)
     411            7204 :   put_short_le(data, bufptr);
     412                 :     else 
     413            7204 :   put_short_be(data, bufptr);
     414           14408 : }
     415                 : 
     416             256 : static void put_unsigned_short(blxcontext_t *ctx, unsigned short data, unsigned char **bufptr) {
     417             256 :     if(ctx->endian == LITTLEENDIAN)
     418             128 :   put_unsigned_short_le(data, bufptr);
     419                 :     else 
     420             128 :   put_unsigned_short_be(data, bufptr);
     421             256 : }
     422                 : 
     423              66 : static int get_int32(blxcontext_t *ctx, unsigned char **data) {
     424                 :     int result;
     425                 : 
     426              66 :     if(ctx->endian == LITTLEENDIAN)
     427              36 :   result = *(*data) | (*(*data+1)<<8) | (*(*data+2)<<16) | (*((char *)*data+3)<<24);
     428                 :     else 
     429              30 :   result = *(*data+3) | (*(*data+2)<<8) | (*(*data+1)<<16) | (*((char *)*data)<<24);
     430              66 :     *data+=4;
     431              66 :     return result;
     432                 : }
     433                 : 
     434             152 : static void put_int32(blxcontext_t *ctx, int data, unsigned char **bufptr) {
     435             152 :     if(ctx->endian == LITTLEENDIAN) {
     436              76 :   *(*bufptr)++ = (unsigned char)(data & 0xff);
     437              76 :   *(*bufptr)++ = (unsigned char)((data>>8) & 0xff);
     438              76 :   *(*bufptr)++ = (unsigned char)((data>>16) & 0xff);
     439              76 :   *(*bufptr)++ = (unsigned char)((data>>24) & 0xff);
     440                 :     } else {
     441              76 :   *(*bufptr)++ = (unsigned char)((data>>24) & 0xff);
     442              76 :   *(*bufptr)++ = (unsigned char)((data>>16) & 0xff);
     443              76 :   *(*bufptr)++ = (unsigned char)((data>>8) & 0xff);
     444              76 :   *(*bufptr)++ = (unsigned char)(data & 0xff);
     445                 :     }
     446             152 : }
     447                 : 
     448             352 : static int get_unsigned32(blxcontext_t *ctx, unsigned char **data) {
     449                 :     int result;
     450                 : 
     451             352 :     if(ctx->endian == LITTLEENDIAN)
     452             192 :   result = *(*data) | (*(*data+1)<<8) | (*(*data+2)<<16) | (*(*data+3)<<24);
     453                 :     else 
     454             160 :   result = *(*data+3) | (*(*data+2)<<8) | (*(*data+1)<<16) | (*(*data)<<24);
     455             352 :     *data+=4;
     456             352 :     return result;
     457                 : }
     458                 : 
     459                 : /* Check native endian order */
     460             240 : int is_big_endian(void)
     461                 : {
     462             240 :   short int word = 0x0001;
     463             240 :   char *byte = (char *) &word;
     464             240 :   return (byte[0] ? 0:1);
     465                 : }
     466              56 : double doubleSWAP(double df)
     467                 : {
     468                 :   union
     469                 :   {
     470                 :     double df;
     471                 :     unsigned char b[8];
     472                 :   } dat1, dat2;
     473                 : 
     474              56 :   dat1.df = df;
     475              56 :   dat2.b[0] = dat1.b[7];
     476              56 :   dat2.b[1] = dat1.b[6];
     477              56 :   dat2.b[2] = dat1.b[5];
     478              56 :   dat2.b[3] = dat1.b[4];
     479              56 :   dat2.b[4] = dat1.b[3];
     480              56 :   dat2.b[5] = dat1.b[2];
     481              56 :   dat2.b[6] = dat1.b[1];
     482              56 :   dat2.b[7] = dat1.b[0];
     483              56 :   return dat2.df;
     484                 : }
     485                 : 
     486              88 : static double get_double(blxcontext_t *ctx, unsigned char **data) {
     487                 :     double result;
     488              88 :     memcpy(&result, *data, sizeof(double));
     489             264 :     if((is_big_endian() && ctx->endian == LITTLEENDIAN) ||
     490             176 :        (!is_big_endian() && ctx->endian == BIGENDIAN))
     491              40 :   result = doubleSWAP(result);
     492                 : 
     493              88 :     *data+=sizeof(double);
     494                 : 
     495              88 :     return result;
     496                 : }
     497                 : 
     498              32 : static void put_double(blxcontext_t *ctx, double data, unsigned char **bufptr) {
     499              96 :     if((is_big_endian() && ctx->endian == LITTLEENDIAN) ||
     500              64 :        (!is_big_endian() && ctx->endian == BIGENDIAN))
     501              16 :   data = doubleSWAP(data);
     502              32 :     memcpy(*bufptr, &data, sizeof(double));
     503              32 :     *bufptr+=sizeof(double);
     504              32 : }
     505                 : 
     506             128 : static void put_cellindex_entry(blxcontext_t *ctx, struct cellindex_s *ci, unsigned char **buffer) {
     507             128 :     put_int32(ctx, (int)ci->offset, buffer);
     508             128 :     put_unsigned_short(ctx, (unsigned short)ci->datasize, buffer);
     509             128 :     put_unsigned_short(ctx, (unsigned short)ci->compdatasize, buffer);
     510             128 : }
     511                 :      
     512                 : /* Transpose matrix in-place */
     513            1456 : static void transpose(blxdata *data, int rows, int cols) {
     514                 :     int i,j;
     515                 :     blxdata tmp;
     516                 : 
     517           46896 :     for(i=0; i<rows; i++)  
     518         1064640 :   for(j=i+1; j<cols; j++) {
     519         1019200 :       tmp=data[i*cols+j];
     520         1019200 :       data[i*cols+j]=data[j*cols+i];
     521         1019200 :       data[j*cols+i]=tmp;
     522                 :   }
     523            1456 : }
     524                 : 
     525                 : struct lutentry_s {
     526                 :     blxdata value;
     527                 :     int frequency;
     528                 : };  
     529          132468 : int lutcmp(const void *aa, const void *bb) {
     530          132468 :     const struct lutentry_s *a=aa, *b=bb;
     531                 : 
     532          132468 :     return b->frequency - a->frequency;
     533                 : }
     534                 : 
     535                 : 
     536              64 : int blx_encode_celldata(blxcontext_t *ctx, blxdata *indata, int side, unsigned char *outbuf, int outbufsize) {
     537              64 :     unsigned char *p=outbuf, *tmpdata, *coutstart, *cout=NULL;
     538                 :     int level, cn, coutsize, zeros;
     539              64 :     blxdata *vdec=NULL, *vdiff=NULL, *c[4], *tc1, *clut, *indata_scaled;
     540                 : 
     541                 :     struct lutentry_s lut[256];
     542              64 :     int lutsize=0;
     543                 : 
     544                 :     int i,j;
     545                 :         
     546              64 :     *p++ = (unsigned char)(side/32-4); /* Resolution */
     547                 :     
     548                 :     /* Allocated memory for buffers */
     549              64 :     indata_scaled = BLXmalloc(sizeof(blxdata)*side*side);
     550              64 :     vdec = BLXmalloc(sizeof(blxdata)*side*side/2);
     551              64 :     vdiff = BLXmalloc(sizeof(blxdata)*side*side/2);
     552             320 :     for(cn=0; cn<4; cn++) 
     553             256 :   c[cn] = BLXmalloc(sizeof(blxdata)*side*side/4);
     554              64 :     tc1 = BLXmalloc(sizeof(blxdata)*side*side/4);
     555              64 :     tmpdata = BLXmalloc(5*4*side*side/4); 
     556                 : 
     557                 :     /* Scale indata and process undefined values*/
     558         1048640 :     for(i=0; i<side*side; i++) {
     559         1048576 :   if((indata[i] == BLX_UNDEF) && ctx->fillundef)
     560               0 :         indata[i] = (blxdata)ctx->fillundefval;
     561         1048576 :       indata_scaled[i] = (blxdata)(indata[i] / ctx->zscale);
     562                 :     }
     563                 : 
     564              64 :     indata = indata_scaled;
     565                 :     
     566              64 :     cout = tmpdata;
     567                 : 
     568             384 :     for(level=0; level < 5; level++) {
     569             320 :   if(ctx->debug) {
     570               0 :       BLXdebug1("\nlevel=%d\n", level);
     571                 :   }
     572             320 :   decimate_vert(indata, side, side, vdec, vdiff);
     573             320 :   decimate_horiz(vdec, side/2, side, c[0], c[1]);
     574             320 :   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            8256 :   for(i=0; i<side/2; i++)  
     578          357120 :       for(j=0; j<side/2; j++) {
     579          349184 :     tc1[j*side/2+i] = c[1][i*side/2+j];
     580          349184 :     tc1[i*side/2+j] = c[1][j*side/2+i];
     581                 :       }
     582                 :   
     583            1280 :   for(cn=1; cn<4; cn++) {
     584                 :       /* Use the possibly transposed version of c when building lut */
     585             960 :       if(cn==1)
     586             320 :     clut=tc1;
     587                 :       else
     588             640 :     clut=c[cn];
     589                 : 
     590             960 :       lutsize=0;
     591             960 :       coutstart = cout;
     592         1048512 :       for(i=0; i<side*side/4; i++) {
     593                 :     /* Find element in lookup table */
     594         1047552 :     for(j=0; (j<lutsize) && (lut[j].value != clut[i]); j++);
     595                 :     
     596         1047552 :     if(clut[i] != 0) {
     597          913276 :         if(j==lutsize) {  
     598           37272 :       lut[lutsize].value=clut[i]; 
     599           37272 :       lut[lutsize].frequency=1;
     600           37272 :       lutsize++;
     601           37272 :       if(lutsize >= 255) 
     602               0 :           break;
     603                 :         } else
     604          876004 :       lut[j].frequency++;
     605                 :     }
     606                 :       }
     607             960 :       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             960 :     qsort(lut, lutsize, sizeof(struct lutentry_s), lutcmp);
     611                 :     
     612             960 :     zeros = 0;
     613         1048512 :     for(i=0; i<side*side/4; i++) {
     614         1047552 :         if(clut[i] == 0) 
     615          134276 :       zeros++;
     616         1047552 :         if(((zeros>0) && (clut[i]!=0)) || (zeros >= 0x100-lutsize)) {
     617           96376 :       *cout++ = (unsigned char)(0x100-zeros); 
     618           96376 :       zeros=0;
     619                 :         }
     620         1047552 :         if(clut[i] != 0) {
     621          913276 :       for(j=0; (j<lutsize) && (lut[j].value != clut[i]); j++);
     622          913276 :       *cout++ = (unsigned char)j;
     623                 :         }
     624                 :     }
     625             960 :     if(zeros>0) 
     626              48 :         *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             960 :       coutsize = cout-coutstart;
     632            1568 :       if((lutsize < 255) && (coutsize+2*lutsize+1 < 2*side*side/4) && (level < 4)) {
     633             608 :     *p++ = (unsigned char)(lutsize+1);
     634           28084 :     for(j=0; j<lutsize; j++) 
     635           27476 :         put_short_le(lut[j].value, &p);
     636             608 :     put_short_le((short)coutsize, &p);
     637                 : 
     638             608 :     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             352 :     *p++=0;
     647             352 :     cout = coutstart;
     648           13664 :     for(i=0; i<side*side/4; i++)
     649           13312 :         put_short(ctx, c[cn][i], &cout);
     650                 :       }
     651                 :   }
     652                 : 
     653             320 :   side >>= 1;
     654             320 :   indata = c[0];
     655                 :     }
     656                 : 
     657              64 :     memcpy(p, tmpdata, cout-tmpdata);
     658              64 :     p += cout-tmpdata;
     659                 : 
     660            1088 :     for(i=0; i<side*side; i++)
     661            1024 :   put_short(ctx, indata[i], &p);
     662                 : 
     663              64 :     *p++=0;
     664                 : 
     665              64 :     BLXfree(indata_scaled);
     666              64 :     BLXfree(vdec); BLXfree(vdiff); 
     667             320 :     for(cn=0; cn<4; cn++) 
     668             256 :   BLXfree(c[cn]);
     669              64 :     BLXfree(tc1);
     670              64 :     BLXfree(tmpdata);
     671                 : 
     672              64 :     return p-outbuf;
     673                 : }
     674                 : 
     675             384 : STATIC blxdata *decode_celldata(blxcontext_t *ctx, unsigned char *inbuf, int len, int *side, blxdata *outbuf, int outbufsize, int overviewlevel) {
     676             384 :     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             384 :     if (len < 1)
     683                 :     {
     684               0 :         BLXerror0("Cell corrupt");
     685               0 :         return NULL;
     686                 :     }
     687             384 :     resolution = *inptr++;
     688             384 :     len --;
     689                 : 
     690             384 :     tmp = (resolution+4)*32;
     691            4608 :     for(div=1; div<12; div++) 
     692            4224 :   baseside[div-1] = tmp >> div;
     693                 : 
     694             384 :     if(side != NULL)
     695               0 :   *side = tmp >> overviewlevel;
     696                 : 
     697             384 :     cellsize = tmp*tmp;
     698             384 :     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             384 :     if(outbuf == NULL) {
     705               0 :   BLXerror0("outbuf is NULL");
     706               0 :   return NULL;
     707                 :     }
     708                 : 
     709             384 :     if(ctx->debug) {
     710               0 :   BLXdebug0("==============================\n");
     711                 :     }
     712                 :     
     713             384 :     base = BLXmalloc(2 * baseside[0] * baseside[0] * sizeof(blxdata));
     714             384 :     diff = BLXmalloc(2 * baseside[0] * baseside[0] * sizeof(blxdata));
     715             384 :     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             384 :     memset(linfo, 0, sizeof(linfo));
     724                 : 
     725            2304 :     for(level=0; level < 5; level++) {
     726            7680 :   for(c=1; c < 4; c++) {
     727            5760 :             if (len < 1)
     728                 :             {
     729               0 :                 BLXerror0("Cell corrupt");
     730               0 :                 outbuf = NULL;
     731               0 :                 goto error;
     732                 :             }
     733            5760 :       n = *inptr++;
     734            5760 :             len --;
     735            5760 :       linfo[level][c].n = n;
     736            5760 :       if(n>0) {
     737            4288 :     linfo[level][c].lut = BLXmalloc(sizeof(blxdata)*(n-1)); 
     738            4288 :                 if (len < (int)sizeof(short) * n)
     739                 :                 {
     740               0 :                     BLXerror0("Cell corrupt");
     741               0 :                     outbuf = NULL;
     742               0 :                     goto error;
     743                 :                 }
     744           88456 :     for(i=0; i<n-1; i++) 
     745           84168 :         linfo[level][c].lut[i] = (blxdata)get_short_le(&inptr);
     746            4288 :     linfo[level][c].dlen = get_short_le(&inptr);
     747            4288 :                 len -= sizeof(short) * n;
     748                 :       } else {
     749            1472 :     linfo[level][c].dlen = 0;
     750                 :       }
     751                 :   }   
     752                 :     }
     753                 : 
     754            2304 :     for(level=0; level < 5; level++) {
     755            1920 :   if(ctx->debug) {
     756               0 :       BLXdebug1("\nlevel=%d\n", level);
     757                 :   }
     758                 : 
     759            1920 :   linfo[level][0].data = BLXmalloc(baseside[level]*baseside[level]*sizeof(blxdata));
     760            1920 :         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            7680 :   for(c=1; c < 4; c++) {
     768            5760 :       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            5760 :       linfo[level][c].data = BLXmalloc(baseside[level]*baseside[level]*sizeof(blxdata));
     777            5760 :             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            5760 :       if(linfo[level][c].n == 0) {
     785            1472 :                 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           40384 :     for(i=0; i<baseside[level]*baseside[level]; i++)
     792           38912 :         linfo[level][c].data[i] = (blxdata)get_short(ctx, &inptr);
     793            1472 :                 len -= sizeof(short) * baseside[level]*baseside[level];
     794                 :       } else {
     795            4288 :     dpos = 0;
     796            4288 :                 if (len < linfo[level][c].dlen)
     797                 :                 {
     798               0 :                     BLXerror0("Cell corrupt");
     799               0 :                     outbuf = NULL;
     800               0 :                     goto error;
     801                 :                 }
     802         4890136 :     for(i=0; i<linfo[level][c].dlen; i++) {
     803         4885848 :         v = *inptr++;
     804         4885848 :         if(v >= linfo[level][c].n-1) {
     805         1098904 :                         if(dpos + 256-v > baseside[level]*baseside[level]) {
     806               0 :                             BLXerror0("Cell corrupt\n");
     807               0 :                             outbuf = NULL;
     808               0 :                             goto error;
     809                 :                         }
     810         3558360 :       for(j=0; j<256-v; j++)
     811         2459456 :           linfo[level][c].data[dpos++] = 0;
     812                 :         }
     813                 :                     else
     814                 :                     {
     815         3786944 :                         if(dpos + 1 > baseside[level]*baseside[level]) {
     816               0 :                             BLXerror0("Cell corrupt\n");
     817               0 :                             outbuf = NULL;
     818               0 :                             goto error;
     819                 :                         }
     820         3786944 :       linfo[level][c].data[dpos++]=linfo[level][c].lut[v];
     821                 :                     }
     822                 :     }
     823            4288 :                 len -= linfo[level][c].dlen;  
     824            4288 :     if(c==1)
     825            1456 :         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             384 :     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            6528 :     for(i=0; i<baseside[4]*baseside[4]; i++)
     847            6144 :   linfo[4][0].data[i] = (blxdata)get_short(ctx, &inptr);
     848             384 :     len -=sizeof(short) * baseside[4]*baseside[4];
     849                 :     
     850            1984 :     for(level=4; level >= overviewlevel; level--) {
     851            1600 :   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            1600 :   reconstruct_horiz(linfo[level][0].data, linfo[level][1].data, baseside[level], baseside[level], base);
     865            1600 :   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            1600 :   reconstruct_horiz(linfo[level][2].data, linfo[level][3].data, baseside[level], baseside[level], diff);  
     873            1600 :   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            1600 :   if(level>overviewlevel) 
     880            1216 :       reconstruct_vert(base, diff, baseside[level], 2*baseside[level], linfo[level-1][0].data);
     881                 :   else  
     882             384 :       reconstruct_vert(base, diff, baseside[level], 2*baseside[level], outbuf);
     883                 :     }    
     884                 : 
     885             384 :     if(overviewlevel == 0) {
     886             256 :         if (len < 1)
     887                 :         {
     888               0 :             BLXerror0("Cell corrupt");
     889               0 :             outbuf = NULL;
     890               0 :             goto error;
     891                 :         }
     892             256 :   a = *((char *)inptr++);
     893             256 :         len --;
     894             256 :   index=0;
     895             512 :   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             256 :         if (len != 0)
     917               0 :             BLXdebug1("remaining len=%d", len);
     918                 :     }
     919                 :     else
     920                 :     {
     921             128 :         if (len != 1)
     922               0 :             BLXdebug1("remaining len=%d", len);
     923                 :     }
     924                 : 
     925                 :     /* Scale data */
     926         6291840 :     for(i=0; i<cellsize; i++)
     927         6291456 :   outbuf[i] = outbuf[i] * (blxdata)ctx->zscale;
     928                 : 
     929                 : 
     930                 :  error:
     931             384 :     if (base != NULL)
     932             384 :          BLXfree(base);
     933             384 :     if (diff != NULL)
     934             384 :          BLXfree(diff);
     935                 : 
     936                 :     /* Free allocated memory */
     937            2304 :     for(level=4; level >= 0; level--) 
     938            9600 :   for(c=0; c<4; c++) {
     939            7680 :       if(linfo[level][c].lut)
     940            4288 :     BLXfree(linfo[level][c].lut);
     941            7680 :       if(linfo[level][c].data)
     942            7680 :     BLXfree(linfo[level][c].data);
     943                 :   }
     944                 : 
     945             384 :     return outbuf;
     946                 : }
     947                 : 
     948              30 : blxcontext_t *blx_create_context() {
     949                 :     blxcontext_t *c;
     950                 :     
     951              30 :     c = BLXmalloc(sizeof(blxcontext_t));
     952                 :     
     953              30 :     memset(c,0,sizeof(blxcontext_t));
     954                 :     
     955              30 :     c->cell_ysize = c->cell_xsize = 128;
     956                 :     
     957              30 :     c->minval = 32767;
     958              30 :     c->maxval = -32768;
     959                 : 
     960              30 :     c->debug = 0;
     961                 : 
     962              30 :     c->zscale = 1;
     963                 : 
     964              30 :     c->fillundef = 1;  
     965              30 :     c->fillundefval = 0;
     966                 : 
     967              30 :     return c;
     968                 : }
     969                 : 
     970              30 : void blx_free_context(blxcontext_t *ctx) {
     971              30 :     if(ctx->cellindex) 
     972              26 :   BLXfree(ctx->cellindex);
     973                 : 
     974              30 :     BLXfree(ctx);
     975              30 : }
     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             846 : int blx_checkheader(char *header) {
     990             846 :     short *signature=(short *)header;
     991                 : 
     992            1690 :     return ((signature[0]==0x4) && (signature[1]==0x66)) ||
     993             844 :   ((signature[0]==0x400) && (signature[1]==0x6600));
     994                 : }
     995                 : 
     996               8 : void blx_generate_header(blxcontext_t *ctx, unsigned char *header) {
     997               8 :     unsigned char *hptr = header;
     998                 :     
     999               8 :     memset(header, 0, 102);
    1000                 : 
    1001                 :     /* Write signature */
    1002               8 :     put_short(ctx, 0x4, &hptr); // 0
    1003               8 :     put_short(ctx, 0x66, &hptr); // 2
    1004                 : 
    1005               8 :     put_int32(ctx, ctx->cell_xsize*ctx->cell_cols, &hptr); // 4
    1006               8 :     put_int32(ctx, ctx->cell_ysize*ctx->cell_rows, &hptr); // 8
    1007                 : 
    1008               8 :     put_short(ctx, (short)ctx->cell_xsize, &hptr); // 12
    1009               8 :     put_short(ctx, (short)ctx->cell_ysize, &hptr); // 14
    1010                 : 
    1011               8 :     put_short(ctx, (short)ctx->cell_cols, &hptr); // 16
    1012               8 :     put_short(ctx, (short)ctx->cell_rows, &hptr); // 18
    1013                 : 
    1014               8 :     put_double(ctx, ctx->lon, &hptr); // 20
    1015               8 :     put_double(ctx, -ctx->lat, &hptr); // 28
    1016                 : 
    1017               8 :     put_double(ctx, ctx->pixelsize_lon, &hptr);  // 36 
    1018               8 :     put_double(ctx, -ctx->pixelsize_lat, &hptr); // 44
    1019                 : 
    1020               8 :     put_short(ctx, (short)ctx->minval, &hptr); // 52
    1021               8 :     put_short(ctx, (short)ctx->maxval, &hptr); // 54
    1022               8 :     put_short(ctx, (short)ctx->zscale, &hptr); // 56
    1023               8 :     put_int32(ctx, ctx->maxchunksize, &hptr); // 58
    1024                 :     // 62
    1025               8 : }
    1026                 : 
    1027              64 : int blx_writecell(blxcontext_t *ctx, blxdata *cell, int cellrow, int cellcol) {
    1028              64 :     unsigned char *uncompbuf=NULL,*outbuf=NULL;
    1029                 :     int bufsize, uncompsize, compsize;
    1030              64 :     int status=0;
    1031                 :     int i,allundef;
    1032                 : 
    1033                 :     /* Calculate statistics and find out if all elements have undefined values */
    1034              64 :     allundef=1;
    1035         1048640 :     for(i=0; i < ctx->cell_xsize*ctx->cell_ysize; i++) {
    1036         1048576 :   if(cell[i] > ctx->maxval)
    1037             448 :       ctx->maxval = cell[i];
    1038         1048576 :   if(cell[i] < ctx->minval)
    1039              28 :       ctx->minval = cell[i];
    1040         1048576 :   if(cell[i]!=BLX_UNDEF)
    1041         1048576 :       allundef=0;
    1042                 :     }   
    1043                 : 
    1044              64 :     if(allundef)
    1045               0 :   return status;
    1046                 : 
    1047              64 :     if(ctx->debug)
    1048               0 :   BLXdebug2("Writing cell (%d,%d)\n",cellrow, cellcol);
    1049                 : 
    1050              64 :     if(!ctx->open) {
    1051               0 :   status=-3;
    1052               0 :   goto error;
    1053                 :     }
    1054                 : 
    1055              64 :     if((cellrow >= ctx->cell_rows) || (cellcol >= ctx->cell_cols)) {
    1056               0 :   status=-2;
    1057               0 :   goto error;
    1058                 :     }
    1059                 :     
    1060              64 :     bufsize = sizeof(blxdata)*ctx->cell_xsize*ctx->cell_ysize+1024;
    1061              64 :     uncompbuf = BLXmalloc(bufsize);
    1062              64 :     outbuf = BLXmalloc(bufsize);
    1063                 :     
    1064              64 :     uncompsize = blx_encode_celldata(ctx, cell, ctx->cell_xsize, uncompbuf, bufsize);
    1065              64 :     compsize = compress_chunk(uncompbuf, uncompsize, outbuf, bufsize);
    1066              64 :     if (compsize < 0)
    1067                 :     {
    1068               0 :         BLXerror0("Couldn't compress chunk");
    1069               0 :         status = -1;
    1070               0 :         goto error;
    1071                 :     }
    1072                 : 
    1073              64 :     if(uncompsize > ctx->maxchunksize)
    1074              24 :   ctx->maxchunksize = uncompsize;
    1075                 :     
    1076              64 :     ctx->cellindex[cellrow*ctx->cell_cols + cellcol].offset = BLXftell(ctx->fh);
    1077              64 :     ctx->cellindex[cellrow*ctx->cell_cols + cellcol].datasize = uncompsize;
    1078              64 :     ctx->cellindex[cellrow*ctx->cell_cols + cellcol].compdatasize = compsize;
    1079                 :     
    1080              64 :     if((int)BLXfwrite(outbuf, 1, compsize, ctx->fh) != compsize) {
    1081               0 :   status=-1;
    1082                 :   goto error;
    1083                 :     }
    1084                 :     
    1085                 :  error:
    1086              64 :     if(uncompbuf) 
    1087              64 :   BLXfree(uncompbuf);
    1088              64 :     if(outbuf)
    1089              64 :   BLXfree(outbuf);
    1090              64 :     return status;
    1091                 : }
    1092                 : 
    1093              30 : 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              52 :     if(!strcmp(rw, "r") || !strcmp(rw, "rb"))
    1100              22 :   ctx->write=0;
    1101               8 :     else if(!strcmp(rw,"w") || !strcmp(rw, "wb"))
    1102               8 :   ctx->write=1;
    1103                 :     else
    1104                 :   goto error;
    1105                 : 
    1106              30 :     ctx->fh = BLXfopen(filename, rw);
    1107                 : 
    1108              30 :     if(ctx->fh == NULL)
    1109               4 :   goto error;
    1110                 : 
    1111              26 :     hptr = header;
    1112              26 :     if(ctx->write) {
    1113               4 :   blx_generate_header(ctx, header);
    1114                 :   
    1115               4 :   if(BLXfwrite(header, 1, 102, ctx->fh) != 102)
    1116               0 :       goto error;
    1117                 : 
    1118               4 :   ctx->cellindex = BLXmalloc(sizeof(struct cellindex_s) * ctx->cell_rows * ctx->cell_cols);
    1119               4 :   if(ctx->cellindex == NULL) {
    1120               0 :       goto error;
    1121                 :   }
    1122               4 :   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              20 :   for(i=0;i<ctx->cell_rows;i++)
    1126              80 :       for(j=0;j<ctx->cell_cols;j++) {
    1127              64 :     hptr = header;
    1128              64 :     put_cellindex_entry(ctx, ctx->cellindex+i*ctx->cell_cols+j, &hptr);
    1129              64 :     if((int)BLXfwrite(header, 1, hptr-header, ctx->fh) != (int)(hptr-header))
    1130               0 :         goto error;
    1131                 :       }
    1132                 : 
    1133                 :     } else {
    1134                 :   /* Read header */
    1135              22 :   if(BLXfread(header, 1, 102, ctx->fh) != 102)
    1136               0 :       goto error;
    1137                 :     
    1138              22 :   signature[0] = get_short_le(&hptr);
    1139              22 :   signature[1] = get_short_le(&hptr);
    1140                 : 
    1141                 :   /* Determine if the endianess of the BLX file */
    1142              34 :   if((signature[0] == 0x4) && (signature[1] == 0x66)) 
    1143              12 :       ctx->endian = LITTLEENDIAN;
    1144                 :   else {  
    1145              10 :       hptr = header;
    1146              10 :       signature[0] = get_short_be(&hptr);
    1147              10 :       signature[1] = get_short_be(&hptr);
    1148              10 :       if((signature[0] == 0x4) && (signature[1] == 0x66)) 
    1149              10 :     ctx->endian = BIGENDIAN;
    1150                 :       else 
    1151                 :     goto error;
    1152                 :   }
    1153                 : 
    1154              22 :   ctx->xsize = get_int32(ctx, &hptr);
    1155              22 :   ctx->ysize = get_int32(ctx, &hptr);
    1156              22 :         if (ctx->xsize <= 0 || ctx->ysize <= 0)
    1157                 :         {
    1158               0 :             BLXerror0("Invalid raster size");
    1159               0 :             goto error;
    1160                 :         }
    1161                 : 
    1162              22 :   ctx->cell_xsize = get_short(ctx, &hptr);
    1163              22 :   ctx->cell_ysize = get_short(ctx, &hptr);
    1164              44 :         if (ctx->cell_xsize <= 0 ||
    1165              22 :             ctx->cell_ysize <= 0)
    1166                 :         {
    1167               0 :             BLXerror0("Invalid cell size");
    1168               0 :             goto error;
    1169                 :         }
    1170                 : 
    1171              22 :   ctx->cell_cols = get_short(ctx, &hptr);
    1172              22 :   ctx->cell_rows = get_short(ctx, &hptr);
    1173              66 :         if (ctx->cell_cols <= 0 || ctx->cell_cols > 10000 ||
    1174              44 :             ctx->cell_rows <= 0 || ctx->cell_rows > 10000)
    1175                 :         {
    1176               0 :             BLXerror0("Invalid cell number");
    1177               0 :             goto error;
    1178                 :         }
    1179                 : 
    1180              22 :   ctx->lon = get_double(ctx, &hptr);
    1181              22 :   ctx->lat = -get_double(ctx, &hptr);
    1182                 : 
    1183              22 :   ctx->pixelsize_lon = get_double(ctx, &hptr);
    1184              22 :   ctx->pixelsize_lat = -get_double(ctx, &hptr);
    1185                 :     
    1186              22 :   ctx->minval = get_short(ctx, &hptr); 
    1187              22 :   ctx->maxval = get_short(ctx, &hptr);
    1188              22 :   ctx->zscale = get_short(ctx, &hptr);
    1189              22 :   ctx->maxchunksize = get_int32(ctx, &hptr);
    1190                 : 
    1191              22 :   ctx->cellindex = BLXmalloc(sizeof(struct cellindex_s) * ctx->cell_rows * ctx->cell_cols);
    1192              22 :   if(ctx->cellindex == NULL) {
    1193               0 :       goto error;
    1194                 :   }
    1195                 : 
    1196             110 :   for(i=0;i<ctx->cell_rows;i++)
    1197             440 :       for(j=0;j<ctx->cell_cols;j++) {
    1198                 :     /* Read cellindex entry */
    1199             352 :     if(BLXfread(header, 1, 8, ctx->fh) != 8)
    1200               0 :         goto error;
    1201             352 :     hptr=header;
    1202                 : 
    1203             352 :     ci = &ctx->cellindex[i*ctx->cell_cols + j]; 
    1204             352 :     ci->offset = get_unsigned32(ctx, &hptr);
    1205             352 :     ci->datasize = get_unsigned_short(ctx, &hptr);
    1206             352 :     ci->compdatasize = get_unsigned_short(ctx, &hptr);
    1207                 :       }
    1208                 :     }
    1209              26 :     ctx->open = 1;
    1210                 : 
    1211              26 :     return 0;
    1212                 : 
    1213                 :  error:
    1214               4 :     return -1;
    1215                 : }
    1216                 : 
    1217              26 : int blxclose(blxcontext_t *ctx) {
    1218                 :     unsigned char header[102],*hptr;
    1219              26 :     int i,j,status=0;
    1220                 : 
    1221              26 :     if(ctx->write) {
    1222                 :   /* Write updated header and cellindex */
    1223               4 :   BLXfseek(ctx->fh, 0, SEEK_SET);
    1224                 : 
    1225               4 :   blx_generate_header(ctx, header);
    1226                 :   
    1227               4 :   if(BLXfwrite(header, 1, 102, ctx->fh) != 102) {
    1228               0 :       status=-1;
    1229               0 :       goto error;
    1230                 :   }
    1231              20 :   for(i=0;i<ctx->cell_rows;i++)
    1232              80 :       for(j=0;j<ctx->cell_cols;j++) {
    1233              64 :     hptr = header;
    1234              64 :     put_cellindex_entry(ctx, ctx->cellindex+i*ctx->cell_cols+j, &hptr);
    1235              64 :     if((int)BLXfwrite(header, 1, hptr-header, ctx->fh) != (int)(hptr-header)) {
    1236               0 :         status=-1;  
    1237               0 :         break;
    1238                 :     }
    1239                 :       }
    1240                 :     }
    1241              26 :     ctx->open = 1;
    1242                 : 
    1243                 :  error: 
    1244              26 :     if(ctx->fh)
    1245              26 :   BLXfclose(ctx->fh);
    1246                 :     
    1247              26 :     return status;
    1248                 : }
    1249                 : 
    1250             384 : short *blx_readcell(blxcontext_t *ctx, int row, int col, short *buffer, int bufsize, int overviewlevel) {
    1251                 :     struct cellindex_s *ci;
    1252             384 :     unsigned char *chunk=NULL, *cchunk=NULL;
    1253             384 :     blxdata *tmpbuf=NULL;
    1254                 :     int tmpbufsize,i;
    1255             384 :     short *result=NULL;
    1256                 :     int npoints;
    1257                 :     
    1258             384 :     if((ctx==NULL) || (row >= ctx->cell_rows) || (col >= ctx->cell_cols))
    1259               0 :   return NULL;
    1260                 : 
    1261             384 :     ci = &ctx->cellindex[row*ctx->cell_cols + col];
    1262                 : 
    1263             384 :     npoints = (ctx->cell_xsize*ctx->cell_ysize)>>(2*overviewlevel) ;
    1264             384 :     if (bufsize < npoints * (int)sizeof(short))
    1265               0 :         return NULL;
    1266                 : 
    1267             384 :     if(ci->datasize == 0) {
    1268               0 :   for(i=0; i<npoints; i++)
    1269               0 :       buffer[i] = BLX_UNDEF;
    1270                 :     } else {
    1271             384 :   BLXfseek(ctx->fh, ci->offset, SEEK_SET);
    1272                 : 
    1273             384 :   chunk = BLXmalloc(ci->datasize);
    1274             384 :   cchunk = BLXmalloc(ci->compdatasize);
    1275                 : 
    1276             384 :   if((chunk == NULL) || (cchunk == NULL)) 
    1277                 :       goto error;
    1278                 :     
    1279             384 :   if(BLXfread(cchunk, 1, ci->compdatasize, ctx->fh) != ci->compdatasize)
    1280               0 :       goto error;
    1281                 :     
    1282             384 :         if((unsigned int)uncompress_chunk(cchunk, ci->compdatasize, chunk, ci->datasize) != ci->datasize)
    1283               0 :       goto error;
    1284                 : 
    1285             384 :   tmpbufsize = sizeof(blxdata)*ctx->cell_xsize*ctx->cell_ysize;
    1286             384 :   tmpbuf = BLXmalloc(tmpbufsize);
    1287             384 :         if (tmpbuf == NULL)
    1288               0 :             goto error;
    1289                 :     
    1290             384 :   if (decode_celldata(ctx, chunk, ci->datasize, NULL, tmpbuf, tmpbufsize, overviewlevel) == NULL)
    1291               0 :             goto error;
    1292                 :     
    1293         4368768 :   for(i=0; i<npoints; i++)
    1294         4368384 :       buffer[i] = tmpbuf[i];
    1295                 :     }
    1296                 : 
    1297             384 :     result = buffer;
    1298                 : 
    1299                 :  error:
    1300             384 :     if(chunk)
    1301             384 :   BLXfree(chunk);
    1302             384 :     if(cchunk)
    1303             384 :   BLXfree(cchunk);
    1304             384 :     if(tmpbuf)
    1305             384 :   BLXfree(tmpbuf);
    1306                 : 
    1307             384 :     return result;
    1308                 : }

Generated by: LCOV version 1.7