| 146 | LodepngImageWriter() {} |
| 147 | |
| 148 | bool writeImage(sp<PaletteImage> img, std::ostream &outStream, sp<Palette> pal) override |
| 149 | { |
| 150 | if (pal->colours.size() != 256) |
| 151 | { |
| 152 | LogWarning("Only 256 colour palettes supported (got %u)", |
| 153 | (unsigned)pal->colours.size()); |
| 154 | return false; |
| 155 | } |
| 156 | lodepng::State state; |
| 157 | |
| 158 | state.info_raw.colortype = LCT_PALETTE; |
| 159 | state.info_raw.bitdepth = 8; |
| 160 | state.encoder.auto_convert = 0; |
| 161 | |
| 162 | lodepng_palette_clear(&state.info_raw); |
| 163 | |
| 164 | for (unsigned i = 0; i < 256; i++) |
| 165 | { |
| 166 | auto &c = pal->getColour(i); |
| 167 | auto err = lodepng_palette_add(&state.info_raw, c.r, c.g, c.b, c.a); |
| 168 | if (err) |
| 169 | { |
| 170 | LogWarning("Failed to add palette index %u to PNG: %d: %s", i, err, |
| 171 | lodepng_error_text(err)); |
| 172 | return false; |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | std::vector<unsigned char> outBuf; |
| 177 | PaletteImageLock l(img, ImageLockUse::Read); |
| 178 | auto err = lodepng::encode(outBuf, reinterpret_cast<unsigned char *>(l.getData()), |
| 179 | img->size.x, img->size.y, state); |
| 180 | if (err) |
| 181 | { |
| 182 | LogWarning("Failed to encode PNG: %d: %s", err, lodepng_error_text(err)); |
| 183 | return false; |
| 184 | } |
| 185 | outStream.write(reinterpret_cast<char *>(outBuf.data()), outBuf.size()); |
| 186 | if (!outStream) |
| 187 | { |
| 188 | LogWarning("Failed to write %zu bytes to stream", outBuf.size()); |
| 189 | return false; |
| 190 | } |
| 191 | |
| 192 | LogInfo("Successfully wrote palette PNG image"); |
| 193 | |
| 194 | return true; |
| 195 | } |
| 196 | bool writeImage(sp<RGBImage> img, std::ostream &outStream) override |
| 197 | { |
| 198 | std::vector<unsigned char> outBuf; |