Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/tesseract/src/lstm/stridemap.cpp @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /////////////////////////////////////////////////////////////////////// | |
| 2 // File: stridemap.cpp | |
| 3 // Description: Indexing into a 4-d tensor held in a 2-d Array. | |
| 4 // Author: Ray Smith | |
| 5 // | |
| 6 // (C) Copyright 2016, Google Inc. | |
| 7 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 8 // you may not use this file except in compliance with the License. | |
| 9 // You may obtain a copy of the License at | |
| 10 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 11 // Unless required by applicable law or agreed to in writing, software | |
| 12 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 // See the License for the specific language governing permissions and | |
| 15 // limitations under the License. | |
| 16 /////////////////////////////////////////////////////////////////////// | |
| 17 | |
| 18 #include "stridemap.h" | |
| 19 #include <cassert> // for assert | |
| 20 | |
| 21 namespace tesseract { | |
| 22 | |
| 23 // Returns true if *this is a valid index. | |
| 24 bool StrideMap::Index::IsValid() const { | |
| 25 // Cheap check first. | |
| 26 for (int index : indices_) { | |
| 27 if (index < 0) { | |
| 28 return false; | |
| 29 } | |
| 30 } | |
| 31 for (int d = 0; d < FD_DIMSIZE; ++d) { | |
| 32 if (indices_[d] > MaxIndexOfDim(static_cast<FlexDimensions>(d))) { | |
| 33 return false; | |
| 34 } | |
| 35 } | |
| 36 return true; | |
| 37 } | |
| 38 | |
| 39 // Returns true if the index of the given dimension is the last. | |
| 40 bool StrideMap::Index::IsLast(FlexDimensions dimension) const { | |
| 41 return MaxIndexOfDim(dimension) == indices_[dimension]; | |
| 42 } | |
| 43 | |
| 44 // Given that the dimensions up to and including dim-1 are valid, returns the | |
| 45 // maximum index for dimension dim. | |
| 46 int StrideMap::Index::MaxIndexOfDim(FlexDimensions dim) const { | |
| 47 int max_index = stride_map_->shape_[dim] - 1; | |
| 48 if (dim == FD_BATCH) { | |
| 49 return max_index; | |
| 50 } | |
| 51 assert(0 <= indices_[FD_BATCH]); | |
| 52 const size_t batch = indices_[FD_BATCH]; | |
| 53 if (dim == FD_HEIGHT) { | |
| 54 if (batch >= stride_map_->heights_.size() || stride_map_->heights_[batch] > max_index) { | |
| 55 return max_index; | |
| 56 } | |
| 57 return stride_map_->heights_[batch] - 1; | |
| 58 } | |
| 59 if (batch >= stride_map_->widths_.size() || stride_map_->widths_[batch] > max_index) { | |
| 60 return max_index; | |
| 61 } | |
| 62 return stride_map_->widths_[batch] - 1; | |
| 63 } | |
| 64 | |
| 65 // Adds the given offset to the given dimension. Returns true if the result | |
| 66 // makes a valid index. | |
| 67 bool StrideMap::Index::AddOffset(int offset, FlexDimensions dimension) { | |
| 68 indices_[dimension] += offset; | |
| 69 SetTFromIndices(); | |
| 70 return IsValid(); | |
| 71 } | |
| 72 | |
| 73 // Increments the index in some encapsulated way that guarantees to remain | |
| 74 // valid until it returns false, meaning that the iteration is complete. | |
| 75 bool StrideMap::Index::Increment() { | |
| 76 for (int d = FD_DIMSIZE - 1; d >= 0; --d) { | |
| 77 if (!IsLast(static_cast<FlexDimensions>(d))) { | |
| 78 t_ += stride_map_->t_increments_[d]; | |
| 79 ++indices_[d]; | |
| 80 return true; | |
| 81 } | |
| 82 t_ -= stride_map_->t_increments_[d] * indices_[d]; | |
| 83 indices_[d] = 0; | |
| 84 // Now carry to the next dimension. | |
| 85 } | |
| 86 return false; | |
| 87 } | |
| 88 | |
| 89 // Decrements the index in some encapsulated way that guarantees to remain | |
| 90 // valid until it returns false, meaning that the iteration (that started | |
| 91 // with InitToLast()) is complete. | |
| 92 bool StrideMap::Index::Decrement() { | |
| 93 for (int d = FD_DIMSIZE - 1; d >= 0; --d) { | |
| 94 if (indices_[d] > 0) { | |
| 95 --indices_[d]; | |
| 96 if (d == FD_BATCH) { | |
| 97 // The upper limits of the other dimensions may have changed as a result | |
| 98 // of a different batch index, so they have to be reset. | |
| 99 InitToLastOfBatch(indices_[FD_BATCH]); | |
| 100 } else { | |
| 101 t_ -= stride_map_->t_increments_[d]; | |
| 102 } | |
| 103 return true; | |
| 104 } | |
| 105 indices_[d] = MaxIndexOfDim(static_cast<FlexDimensions>(d)); | |
| 106 t_ += stride_map_->t_increments_[d] * indices_[d]; | |
| 107 // Now borrow from the next dimension. | |
| 108 } | |
| 109 return false; | |
| 110 } | |
| 111 | |
| 112 // Initializes the indices to the last valid location in the given batch | |
| 113 // index. | |
| 114 void StrideMap::Index::InitToLastOfBatch(int batch) { | |
| 115 indices_[FD_BATCH] = batch; | |
| 116 for (int d = FD_BATCH + 1; d < FD_DIMSIZE; ++d) { | |
| 117 indices_[d] = MaxIndexOfDim(static_cast<FlexDimensions>(d)); | |
| 118 } | |
| 119 SetTFromIndices(); | |
| 120 } | |
| 121 | |
| 122 // Computes and sets t_ from the current indices_. | |
| 123 void StrideMap::Index::SetTFromIndices() { | |
| 124 t_ = 0; | |
| 125 for (int d = 0; d < FD_DIMSIZE; ++d) { | |
| 126 t_ += stride_map_->t_increments_[d] * indices_[d]; | |
| 127 } | |
| 128 } | |
| 129 | |
| 130 // Sets up the stride for the given array of height, width pairs. | |
| 131 void StrideMap::SetStride(const std::vector<std::pair<int, int>> &h_w_pairs) { | |
| 132 int max_height = 0; | |
| 133 int max_width = 0; | |
| 134 for (const std::pair<int, int> &hw : h_w_pairs) { | |
| 135 int height = hw.first; | |
| 136 int width = hw.second; | |
| 137 heights_.push_back(height); | |
| 138 widths_.push_back(width); | |
| 139 if (height > max_height) { | |
| 140 max_height = height; | |
| 141 } | |
| 142 if (width > max_width) { | |
| 143 max_width = width; | |
| 144 } | |
| 145 } | |
| 146 shape_[FD_BATCH] = heights_.size(); | |
| 147 shape_[FD_HEIGHT] = max_height; | |
| 148 shape_[FD_WIDTH] = max_width; | |
| 149 ComputeTIncrements(); | |
| 150 } | |
| 151 | |
| 152 // Scales width and height dimensions by the given factors. | |
| 153 void StrideMap::ScaleXY(int x_factor, int y_factor) { | |
| 154 for (int &height : heights_) { | |
| 155 height /= y_factor; | |
| 156 } | |
| 157 for (int &width : widths_) { | |
| 158 width /= x_factor; | |
| 159 } | |
| 160 shape_[FD_HEIGHT] /= y_factor; | |
| 161 shape_[FD_WIDTH] /= x_factor; | |
| 162 ComputeTIncrements(); | |
| 163 } | |
| 164 | |
| 165 // Reduces width to 1, across the batch, whatever the input size. | |
| 166 void StrideMap::ReduceWidthTo1() { | |
| 167 widths_.assign(widths_.size(), 1); | |
| 168 shape_[FD_WIDTH] = 1; | |
| 169 ComputeTIncrements(); | |
| 170 } | |
| 171 | |
| 172 // Transposes the width and height dimensions. | |
| 173 void StrideMap::TransposeXY() { | |
| 174 std::swap(shape_[FD_HEIGHT], shape_[FD_WIDTH]); | |
| 175 std::swap(heights_, widths_); | |
| 176 ComputeTIncrements(); | |
| 177 } | |
| 178 | |
| 179 // Computes t_increments_ from shape_. | |
| 180 void StrideMap::ComputeTIncrements() { | |
| 181 t_increments_[FD_DIMSIZE - 1] = 1; | |
| 182 for (int d = FD_DIMSIZE - 2; d >= 0; --d) { | |
| 183 t_increments_[d] = t_increments_[d + 1] * shape_[d + 1]; | |
| 184 } | |
| 185 } | |
| 186 | |
| 187 } // namespace tesseract |
