LCOV - code coverage report
Current view: top level - frmts/pcidsk/sdk/blockdir - asciitilelayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 72 78 92.3 %
Date: 2024-11-21 22:18:42 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Purpose:  Block directory API.
       4             :  *
       5             :  ******************************************************************************
       6             :  * Copyright (c) 2011
       7             :  * PCI Geomatics, 90 Allstate Parkway, Markham, Ontario, Canada.
       8             :  *
       9             :  * SPDX-License-Identifier: MIT
      10             :  ****************************************************************************/
      11             : 
      12             : #include "blockdir/asciitilelayer.h"
      13             : #include "blockdir/blockfile.h"
      14             : #include "core/pcidsk_scanint.h"
      15             : #include "pcidsk_exception.h"
      16             : #include "pcidsk_buffer.h"
      17             : #include <cstdlib>
      18             : #include <cstring>
      19             : #include <cstdio>
      20             : #include <algorithm>
      21             : #include <limits>
      22             : 
      23             : using namespace PCIDSK;
      24             : 
      25             : /************************************************************************/
      26             : /*                             AsciiTileLayer()                         */
      27             : /************************************************************************/
      28             : 
      29             : /**
      30             :  * Constructor.
      31             :  *
      32             :  * @param poBlockDir The associated block directory.
      33             :  * @param nLayer The index of the block layer.
      34             :  * @param psBlockLayer The block layer info.
      35             :  * @param psTileLayer The tile layer info.
      36             :  */
      37          22 : AsciiTileLayer::AsciiTileLayer(BlockDir * poBlockDir, uint32 nLayer,
      38             :                                BlockLayerInfo * psBlockLayer,
      39          22 :                                TileLayerInfo * psTileLayer)
      40          22 :     : BlockTileLayer(poBlockDir, nLayer, psBlockLayer, psTileLayer)
      41             : {
      42          22 : }
      43             : 
      44             : /************************************************************************/
      45             : /*                               ReadHeader()                           */
      46             : /************************************************************************/
      47             : 
      48             : /**
      49             :  * Reads the tile layer header from disk.
      50             :  */
      51           5 : void AsciiTileLayer::ReadHeader(void)
      52             : {
      53             :     uint8 abyHeader[128];
      54             : 
      55           5 :     uint8 * pabyHeaderIter = abyHeader;
      56             : 
      57           5 :     ReadFromLayer(abyHeader, 0, 128);
      58             : 
      59           5 :     mpsTileLayer->nXSize = ScanInt8(pabyHeaderIter);
      60           5 :     pabyHeaderIter += 8;
      61             : 
      62           5 :     mpsTileLayer->nYSize = ScanInt8(pabyHeaderIter);
      63           5 :     pabyHeaderIter += 8;
      64             : 
      65           5 :     mpsTileLayer->nTileXSize = ScanInt8(pabyHeaderIter);
      66           5 :     pabyHeaderIter += 8;
      67             : 
      68           5 :     mpsTileLayer->nTileYSize = ScanInt8(pabyHeaderIter);
      69           5 :     pabyHeaderIter += 8;
      70             : 
      71           5 :     memcpy(mpsTileLayer->szDataType, pabyHeaderIter, 4);
      72           5 :     pabyHeaderIter += 4;
      73             : /*
      74             :     std::string oNoDataValue((char *) pabyHeaderIter,
      75             :                              (char *) pabyHeaderIter + 18);
      76             : */
      77           5 :     mpsTileLayer->bNoDataValid = false;
      78           5 :     mpsTileLayer->dfNoDataValue = 0.0;
      79           5 :     pabyHeaderIter += 18;
      80             : 
      81           5 :     memcpy(mpsTileLayer->szCompress, pabyHeaderIter, 8);
      82           5 : }
      83             : 
      84             : /************************************************************************/
      85             : /*                             WriteTileList()                          */
      86             : /************************************************************************/
      87             : 
      88             : /**
      89             :  * Writes the tile list to disk.
      90             :  */
      91           4 : void AsciiTileLayer::WriteTileList(void)
      92             : {
      93           4 :     uint32 nTileCount = GetTileCount();
      94             : 
      95           4 :     size_t nSize = 128 + nTileCount * 20;
      96             : 
      97           4 :     char * pabyTileLayer = (char *) malloc(nSize + 1); // +1 for '\0'.
      98             : 
      99           4 :     if (!pabyTileLayer)
     100           0 :         return ThrowPCIDSKException("Out of memory in AsciiTileLayer::WriteTileList().");
     101             : 
     102           8 :     PCIDSKBuffer oTileLayerAutoPtr;
     103           4 :     oTileLayerAutoPtr.buffer = pabyTileLayer;
     104             : 
     105             :     // Write the tile layer header to disk.
     106           4 :     char * pabyHeaderIter = pabyTileLayer;
     107             : 
     108           4 :     memset(pabyTileLayer, ' ', 128);
     109             : 
     110           4 :     snprintf(pabyHeaderIter, 9, "%8d", mpsTileLayer->nXSize);
     111           4 :     pabyHeaderIter += 8;
     112             : 
     113           4 :     snprintf(pabyHeaderIter, 9, "%8d", mpsTileLayer->nYSize);
     114           4 :     pabyHeaderIter += 8;
     115             : 
     116           4 :     snprintf(pabyHeaderIter, 9, "%8d", mpsTileLayer->nTileXSize);
     117           4 :     pabyHeaderIter += 8;
     118             : 
     119           4 :     snprintf(pabyHeaderIter, 9, "%8d", mpsTileLayer->nTileYSize);
     120           4 :     pabyHeaderIter += 8;
     121             : 
     122           4 :     memcpy(pabyHeaderIter, mpsTileLayer->szDataType, 4);
     123           4 :     pabyHeaderIter += 4;
     124             : 
     125           4 :     if (mpsTileLayer->bNoDataValid)
     126           0 :         snprintf(pabyHeaderIter, 19, "%18.10E", mpsTileLayer->dfNoDataValue);
     127           4 :     pabyHeaderIter += 18;
     128             : 
     129           4 :     memcpy(pabyHeaderIter, mpsTileLayer->szCompress, 8);
     130             : 
     131             :     // Write the tile list to disk.
     132           4 :     char * pabyTileListIter = pabyTileLayer + 128;
     133             : 
     134           8 :     for (uint32 iTile = 0; iTile < nTileCount; iTile++)
     135             :     {
     136           4 :         BlockTileInfo * psTile = &moTileList[iTile];
     137             : 
     138           4 :         snprintf(pabyTileListIter, 13, "%12" PCIDSK_FRMT_64_WITHOUT_PREFIX "d", psTile->nOffset);
     139           4 :         pabyTileListIter += 12;
     140             :     }
     141             : 
     142             :     // We cannot write the offset and the size at the same time because
     143             :     // snprintf() inserts a '\0' in the first character of the first size.
     144           8 :     for (uint32 iTile = 0; iTile < nTileCount; iTile++)
     145             :     {
     146           4 :         BlockTileInfo * psTile = &moTileList[iTile];
     147             : 
     148           4 :         snprintf(pabyTileListIter, 9, "%8d", psTile->nSize);
     149           4 :         pabyTileListIter += 8;
     150             :     }
     151             : 
     152           4 :     WriteToLayer(pabyTileLayer, 0, nSize);
     153             : }
     154             : 
     155             : /************************************************************************/
     156             : /*                              ReadTileList()                          */
     157             : /************************************************************************/
     158             : 
     159             : /**
     160             :  * Reads the tile list from disk.
     161             :  */
     162           5 : void AsciiTileLayer::ReadTileList(void)
     163             : {
     164           5 :     uint32 nTileCount = GetTileCount();
     165             : 
     166           5 :     uint64 nSize = static_cast<uint64>(nTileCount) * 20;
     167             : 
     168           5 :     if (128 + nSize > GetLayerSize() || !GetFile()->IsValidFileOffset(128 + nSize))
     169           0 :         return ThrowPCIDSKException("The tile layer is corrupted.");
     170             : 
     171             : #if SIZEOF_VOIDP < 8
     172             :     if (nSize > std::numeric_limits<size_t>::max())
     173             :         return ThrowPCIDSKException("Unable to open extremely large tile layer on 32-bit system.");
     174             : #endif
     175             : 
     176           5 :     uint8 * pabyTileList = (uint8 *) malloc(static_cast<size_t>(nSize));
     177             : 
     178           5 :     if (!pabyTileList)
     179           0 :         return ThrowPCIDSKException("Out of memory in AsciiTileLayer::ReadTileList().");
     180             : 
     181           5 :     PCIDSKBuffer oTileListAutoPtr;
     182           5 :     oTileListAutoPtr.buffer = (char *) pabyTileList;
     183             : 
     184           5 :     ReadFromLayer(pabyTileList, 128, nSize);
     185             : 
     186           5 :     uint8 * pabyTileOffsetIter = pabyTileList;
     187           5 :     uint8 * pabyTileSizeIter = pabyTileList + nTileCount * 12;
     188             : 
     189             :     try
     190             :     {
     191           5 :         moTileList.resize(nTileCount);
     192             :     }
     193           0 :     catch (const std::exception & ex)
     194             :     {
     195           0 :         return ThrowPCIDSKException("Out of memory in AsciiTileLayer::ReadTileList(): %s", ex.what());
     196             :     }
     197             : 
     198          18 :     for (uint32 iTile = 0; iTile < nTileCount; iTile++)
     199             :     {
     200          13 :         BlockTileInfo * psTile = &moTileList[iTile];
     201             : 
     202          13 :         psTile->nOffset = ScanInt12(pabyTileOffsetIter);
     203          13 :         pabyTileOffsetIter += 12;
     204             : 
     205          13 :         psTile->nSize = ScanInt8(pabyTileSizeIter);
     206          13 :         pabyTileSizeIter += 8;
     207             :     }
     208             : }

Generated by: LCOV version 1.14