LCOV - code coverage report
Current view: top level - frmts/blx - blx.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 653 801 81.5 %
Date: 2024-04-28 21:03:45 Functions: 38 39 97.4 %

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

Generated by: LCOV version 1.14