| 311 | |
| 312 | #ifdef TGFX_USE_JPEG_ENCODE |
| 313 | std::shared_ptr<Data> JpegCodec::Encode(const Pixmap& pixmap, int quality) { |
| 314 | auto srcPixels = static_cast<uint8_t*>(const_cast<void*>(pixmap.pixels())); |
| 315 | int srcRowBytes = static_cast<int>(pixmap.rowBytes()); |
| 316 | jpeg_compress_struct cinfo = {}; |
| 317 | jpeg_error_mgr jerr = {}; |
| 318 | JSAMPROW row_pointer[1]; |
| 319 | cinfo.err = jpeg_std_error(&jerr); |
| 320 | jpeg_create_compress(&cinfo); |
| 321 | uint8_t* dstBuffer = nullptr; |
| 322 | unsigned long dstBufferSize = 0; // NOLINT |
| 323 | jpeg_mem_dest(&cinfo, &dstBuffer, &dstBufferSize); |
| 324 | cinfo.image_width = static_cast<JDIMENSION>(pixmap.width()); |
| 325 | cinfo.image_height = static_cast<JDIMENSION>(pixmap.height()); |
| 326 | Buffer buffer = {}; |
| 327 | switch (pixmap.colorType()) { |
| 328 | case ColorType::RGBA_8888: |
| 329 | cinfo.in_color_space = JCS_EXT_RGBA; |
| 330 | cinfo.input_components = 4; |
| 331 | break; |
| 332 | case ColorType::BGRA_8888: |
| 333 | cinfo.in_color_space = JCS_EXT_BGRA; |
| 334 | cinfo.input_components = 4; |
| 335 | break; |
| 336 | case ColorType::Gray_8: |
| 337 | cinfo.in_color_space = JCS_GRAYSCALE; |
| 338 | cinfo.input_components = 1; |
| 339 | break; |
| 340 | default: |
| 341 | auto info = ImageInfo::Make(pixmap.width(), pixmap.height(), ColorType::RGBA_8888); |
| 342 | buffer.alloc(info.byteSize()); |
| 343 | if (buffer.isEmpty()) { |
| 344 | return nullptr; |
| 345 | } |
| 346 | srcPixels = buffer.bytes(); |
| 347 | srcRowBytes = static_cast<int>(info.rowBytes()); |
| 348 | Pixmap(info, srcPixels).writePixels(pixmap.info(), pixmap.pixels()); |
| 349 | cinfo.in_color_space = JCS_EXT_RGBA; |
| 350 | cinfo.input_components = 4; |
| 351 | break; |
| 352 | } |
| 353 | jpeg_set_defaults(&cinfo); |
| 354 | cinfo.optimize_coding = TRUE; |
| 355 | jpeg_set_quality(&cinfo, quality, TRUE); |
| 356 | jpeg_start_compress(&cinfo, TRUE); |
| 357 | while (cinfo.next_scanline < cinfo.image_height) { |
| 358 | row_pointer[0] = &(srcPixels)[cinfo.next_scanline * static_cast<JDIMENSION>(srcRowBytes)]; |
| 359 | (void)jpeg_write_scanlines(&cinfo, row_pointer, 1); |
| 360 | } |
| 361 | |
| 362 | /* similar to read file, clean up after we're done compressing */ |
| 363 | jpeg_finish_compress(&cinfo); |
| 364 | jpeg_destroy_compress(&cinfo); |
| 365 | return Data::MakeAdopted(dstBuffer, dstBufferSize, Data::FreeProc); |
| 366 | } |
| 367 | #endif |
| 368 | |
| 369 | } // namespace tgfx |
nothing calls this directly
no test coverage detected