Hash.h 5.68 KB
Newer Older
Alberto Gonzalez's avatar
Alberto Gonzalez committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
/* The copyright in this software is being made available under the BSD
 * License, included below. This software may be subject to other third party
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
 * Copyright (c) 2010-2023, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
 *    be used to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

 /** \file     Hash.h
     \brief    Hash class (header)
 */


#ifndef __HASH__
#define __HASH__

 // Include files

#include "CommonLib/Buffer.h"
#include "CommonLib/CommonDef.h"
#include "CommonLib/TrQuant.h"
#include "CommonLib/Unit.h"
#include "CommonLib/UnitPartitioner.h"
#include <vector>


struct BlockHash
{
  short x;
  short y;
  uint32_t hashValue2;
};

typedef std::vector<BlockHash>::iterator MapIterator;

// ====================================================================================================================
// Class definitions
// ====================================================================================================================

struct CrcCalculatorLight
{
public:
  CrcCalculatorLight(uint32_t bits, uint32_t truncPoly);
  ~CrcCalculatorLight();

public:
  void     processData(const uint8_t *curData, size_t dataLength);
  void     reset() { m_remainder = 0; }
  uint32_t getCRC() { return m_remainder & m_finalResultMask; }

private:
  void xInitTable();

private:
  uint32_t m_remainder;
  uint32_t m_truncPoly;
  uint32_t m_bits;
  uint32_t m_table[256];
  uint32_t m_finalResultMask;
};

struct Hash
{
  static constexpr int MIN_LOG_BLK_SIZE  = 2;
  static constexpr int MAX_LOG_BLK_SIZE  = 6;
  static constexpr int NUM_LOG_BLK_SIZES = MAX_LOG_BLK_SIZE - MIN_LOG_BLK_SIZE + 1;
  static constexpr int LOG_SIZE_BITS     = 3;
  static_assert(NUM_LOG_BLK_SIZES <= (1 << LOG_SIZE_BITS), "Hash::LOG_SIZE_BITS is too small");

public:
  Hash();
  ~Hash();
  void create(int picWidth, int picHeight);
  void clearAll();
  void addToTable(uint32_t hashValue, const BlockHash& blockHash);
  int count(uint32_t hashValue);
  int count(uint32_t hashValue) const;
  MapIterator getFirstIterator(uint32_t hashValue);
  const MapIterator getFirstIterator(uint32_t hashValue) const;
  bool hasExactMatch(uint32_t hashValue1, uint32_t hashValue2);

  void generateBlock2x2HashValue(const PelUnitBuf &curPicBuf, int picWidth, int picHeight, const BitDepths bitDepths, uint32_t* picBlockHash[2], bool* picBlockSameInfo[3]);
  void generateBlockHashValue(int picWidth, int picHeight, int width, int height, uint32_t* srcPicBlockHash[2], uint32_t* dstPicBlockHash[2], bool* srcPicBlockSameInfo[3], bool* dstPicBlockSameInfo[3]);
  void addToHashMapByRowWithPrecalData(uint32_t* srcHash[2], bool* srcIsSame, int picWidth, int picHeight, int width, int height);
  bool isInitial() { return tableHasContent; }
  void setInitial() { tableHasContent = true; }
  uint16_t *getHashPic(int baseSize) const { return hashPic[floorLog2(baseSize) - MIN_LOG_BLK_SIZE]; }

public:
  static uint32_t getCRCValue1(const uint8_t *p, size_t length);
  static uint32_t getCRCValue2(const uint8_t *p, size_t length);
  static void getPixelsIn1DCharArrayByBlock2x2(const PelUnitBuf &curPicBuf, unsigned char* pixelsIn1D, int xStart, int yStart, const BitDepths& bitDepths, bool includeAllComponent = true);
  static bool isBlock2x2RowSameValue(unsigned char* p, bool includeAllComponent = true);
  static bool isBlock2x2ColSameValue(unsigned char* p, bool includeAllComponent = true);
  static bool getBlockHashValue(const PelUnitBuf &curPicBuf, int width, int height, int xStart, int yStart, const BitDepths bitDepths, uint32_t& hashValue1, uint32_t& hashValue2);
  static void initBlockSizeToIndex();
  static bool     isHorizontalPerfectLuma(const Pel *srcPel, ptrdiff_t stride, int width, int height);
  static bool     isVerticalPerfectLuma(const Pel *srcPel, ptrdiff_t stride, int width, int height);

private:
  std::vector<BlockHash>** m_lookupTable;
  bool tableHasContent;
  std::array<uint16_t *, NUM_LOG_BLK_SIZES> hashPic;   // 4x4 ~ 64x64

private:
  static constexpr int CRC_BITS = 16;

  static int getIndexFromBlockSize(int w, int h)
  {
    if (w != h)
    {
      return -1;
    }
    return w == 4 ? 4 : floorLog2(w) - 3;
  }

  static CrcCalculatorLight m_crcCalculator1;
  static CrcCalculatorLight m_crcCalculator2;
};

#endif // __HASH__