LCOV - code coverage report
Current view: top level - source/lib/tex - tex_codec.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 30 46 65.2 %
Date: 2023-01-19 00:18:29 Functions: 5 7 71.4 %

          Line data    Source code
       1             : /* Copyright (C) 2014 Wildfire Games.
       2             :  *
       3             :  * Permission is hereby granted, free of charge, to any person obtaining
       4             :  * a copy of this software and associated documentation files (the
       5             :  * "Software"), to deal in the Software without restriction, including
       6             :  * without limitation the rights to use, copy, modify, merge, publish,
       7             :  * distribute, sublicense, and/or sell copies of the Software, and to
       8             :  * permit persons to whom the Software is furnished to do so, subject to
       9             :  * the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included
      12             :  * in all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      15             :  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      16             :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      17             :  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
      18             :  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
      19             :  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      20             :  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      21             :  */
      22             : 
      23             : /*
      24             :  * support routines for texture codecs
      25             :  */
      26             : 
      27             : #include "precompiled.h"
      28             : #include "tex_codec.h"
      29             : 
      30             : #include <string.h>
      31             : #include <stdlib.h>
      32             : 
      33             : #include "lib/allocators/shared_ptr.h" // ArrayDeleter
      34             : #include "tex.h"
      35             : 
      36             : // Statically allocate all of the codecs...
      37           1 : TexCodecDds DdsCodec;
      38           1 : TexCodecPng PngCodec;
      39           1 : TexCodecTga TgaCodec;
      40           1 : TexCodecBmp BmpCodec;
      41             : // Codecs will be searched in this order
      42             : static const ITexCodec *codecs[] = {(ITexCodec *)&DdsCodec, (ITexCodec *)&PngCodec,
      43             :     (ITexCodec *)&TgaCodec, (ITexCodec *)&BmpCodec};
      44             : static const int codecs_len = sizeof(codecs) / sizeof(ITexCodec*);
      45             : 
      46             : // find codec that recognizes the desired output file extension,
      47             : // or return ERR::TEX_UNKNOWN_FORMAT if unknown.
      48             : // note: does not raise a warning because it is used by
      49             : // tex_is_known_extension.
      50           0 : Status tex_codec_for_filename(const OsPath& extension, const ITexCodec** c)
      51             : {
      52           0 :     for(int i = 0; i < codecs_len; ++i)
      53             :     {
      54             :         // we found it
      55           0 :         if(codecs[i]->is_ext(extension)) {
      56           0 :             *c = codecs[i];
      57           0 :             return INFO::OK;
      58             :         }
      59             :     }
      60             : 
      61           0 :     return ERR::TEX_UNKNOWN_FORMAT; // NOWARN
      62             : }
      63             : 
      64             : 
      65             : // find codec that recognizes the header's magic field
      66          14 : Status tex_codec_for_header(const u8* file, size_t file_size, const ITexCodec** c)
      67             : {
      68             :     // we guarantee at least 4 bytes for is_hdr to look at
      69          14 :     if(file_size < 4)
      70           0 :         return ERR::TEX_INCOMPLETE_HEADER;
      71             : 
      72          19 :     for(int i = 0; i < codecs_len; ++i)
      73             :     {
      74             :         // we found it
      75          19 :         if(codecs[i]->is_hdr(file)) {
      76          14 :             *c = codecs[i];
      77          14 :             return INFO::OK;
      78             :         }
      79             :     }
      80             : 
      81           0 :     return ERR::TEX_UNKNOWN_FORMAT;
      82             : }
      83             : 
      84          30 : Status tex_codec_transform(Tex* t, size_t transforms)
      85             : {
      86          30 :     Status ret = INFO::TEX_CODEC_CANNOT_HANDLE;
      87             : 
      88             :     // find codec that understands the data, and transform
      89          82 :     for(int i = 0; i < codecs_len; ++i)
      90             :     {
      91          69 :         Status err = codecs[i]->transform(t, transforms);
      92             :         // success
      93          69 :         if(err == INFO::OK)
      94          17 :             return INFO::OK;
      95             :         // something went wrong
      96          52 :         else if(err != INFO::TEX_CODEC_CANNOT_HANDLE)
      97             :         {
      98           0 :             ret = err;
      99           0 :             DEBUG_WARN_ERR(ERR::LOGIC); // codec indicates error
     100             :         }
     101             :     }
     102             : 
     103          13 :     return ret;
     104             : }
     105             : 
     106             : 
     107             : //-----------------------------------------------------------------------------
     108             : // helper functions used by codecs
     109             : //-----------------------------------------------------------------------------
     110             : 
     111             : // allocate an array of row pointers that point into the given texture data.
     112             : // <file_orientation> indicates whether the file format is top-down or
     113             : // bottom-up; the row array is inverted if necessary to match global
     114             : // orienatation. (this is more efficient than "transforming" later)
     115             : //
     116             : // used by PNG and JPG codecs.
     117             : //
     118             : // note: we don't allocate the data param ourselves because this function is
     119             : // needed for encoding, too (where data is already present).
     120           3 : std::vector<RowPtr> tex_codec_alloc_rows(const u8* data, size_t h, size_t pitch, size_t src_flags, size_t dst_orientation)
     121             : {
     122           3 :     const bool flip = !tex_orientations_match(src_flags, dst_orientation);
     123             : 
     124           3 :     std::vector<RowPtr> rows(h);
     125             : 
     126             :     // determine start position and direction
     127           3 :     RowPtr pos        = flip? data+pitch*(h-1) : data;
     128           3 :     const ssize_t add = flip? -(ssize_t)pitch : (ssize_t)pitch;
     129           3 :     const RowPtr end  = flip? data-pitch : data+pitch*h;
     130             : 
     131          75 :     for(size_t i = 0; i < h; i++)
     132             :     {
     133          72 :         rows[i] = pos;
     134          72 :         pos += add;
     135             :     }
     136             : 
     137           3 :     ENSURE(pos == end);
     138           3 :     return rows;
     139             : }
     140             : 
     141             : 
     142           0 : Status tex_codec_write(Tex* t, size_t transforms, const void* hdr, size_t hdr_size, DynArray* da)
     143             : {
     144           0 :     RETURN_STATUS_IF_ERR(t->transform(transforms));
     145             : 
     146           0 :     void* img_data = t->get_data(); const size_t img_size = t->img_size();
     147           0 :     RETURN_STATUS_IF_ERR(da_append(da, hdr, hdr_size));
     148           0 :     RETURN_STATUS_IF_ERR(da_append(da, img_data, img_size));
     149           0 :     return INFO::OK;
     150           3 : }

Generated by: LCOV version 1.13