| 151 | } |
| 152 | |
| 153 | bool ImageCodec::readPixels(const ImageInfo& dstInfo, void* dstPixels) const { |
| 154 | if (dstInfo.width() > width() || dstInfo.height() > height()) { |
| 155 | return false; |
| 156 | } |
| 157 | if (dstInfo.width() == width() && dstInfo.height() == height()) { |
| 158 | return onReadPixels(dstInfo.colorType(), dstInfo.alphaType(), dstInfo.rowBytes(), dstPixels); |
| 159 | } |
| 160 | |
| 161 | Buffer buffer = {}; |
| 162 | Buffer dstTempBuffer = {}; |
| 163 | auto dstData = dstPixels; |
| 164 | auto dstImageInfo = dstInfo; |
| 165 | auto colorType = dstInfo.colorType(); |
| 166 | auto srcRowBytes = dstInfo.bytesPerPixel() * static_cast<size_t>(width()); |
| 167 | if (dstInfo.colorType() != ColorType::RGBA_8888 && dstInfo.colorType() != ColorType::BGRA_8888 && |
| 168 | dstInfo.colorType() != ColorType::ALPHA_8 && dstInfo.colorType() != ColorType::Gray_8) { |
| 169 | colorType = ColorType::RGBA_8888; |
| 170 | srcRowBytes = ImageInfo::GetBytesPerPixel(colorType) * static_cast<size_t>(width()); |
| 171 | dstImageInfo = dstInfo.makeColorType(colorType); |
| 172 | auto dstRowBytes = dstImageInfo.rowBytes(); |
| 173 | if (dstRowBytes % 16) { |
| 174 | dstRowBytes = dstImageInfo.rowBytes() + GetPaddingAlignment16(dstImageInfo.rowBytes()); |
| 175 | dstImageInfo = ImageInfo::Make(dstInfo.width(), dstInfo.height(), colorType, |
| 176 | dstInfo.alphaType(), dstRowBytes); |
| 177 | } |
| 178 | if (!dstTempBuffer.alloc(dstImageInfo.byteSize())) { |
| 179 | return false; |
| 180 | } |
| 181 | dstData = dstTempBuffer.bytes(); |
| 182 | } |
| 183 | srcRowBytes = srcRowBytes + GetPaddingAlignment16(srcRowBytes); |
| 184 | if (!buffer.alloc(srcRowBytes * static_cast<size_t>(height()))) { |
| 185 | return false; |
| 186 | } |
| 187 | auto result = onReadPixels(colorType, dstInfo.alphaType(), srcRowBytes, buffer.data()); |
| 188 | if (!result) { |
| 189 | return false; |
| 190 | } |
| 191 | auto isOneComponent = dstImageInfo.colorType() == ColorType::Gray_8 || |
| 192 | dstImageInfo.colorType() == ColorType::ALPHA_8; |
| 193 | auto inputLayout = PixelLayout{width(), height(), static_cast<int>(srcRowBytes)}; |
| 194 | auto outputLayout = PixelLayout{dstImageInfo.width(), dstImageInfo.height(), |
| 195 | static_cast<int>(dstImageInfo.rowBytes())}; |
| 196 | BoxFilterDownsample(buffer.data(), inputLayout, dstData, outputLayout, isOneComponent); |
| 197 | if (!dstTempBuffer.isEmpty()) { |
| 198 | Pixmap(dstImageInfo, dstData).readPixels(dstInfo, dstPixels); |
| 199 | } |
| 200 | return true; |
| 201 | } |
| 202 | |
| 203 | std::shared_ptr<ImageBuffer> ImageCodec::onMakeBuffer(bool tryHardware) const { |
| 204 | auto pixelBuffer = PixelBuffer::Make(width(), height(), isAlphaOnly(), tryHardware); |
nothing calls this directly
no test coverage detected