| 3522 | } |
| 3523 | |
| 3524 | unsigned lodepng_convert(unsigned char* out, const unsigned char* in, |
| 3525 | const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, |
| 3526 | unsigned w, unsigned h) { |
| 3527 | size_t i; |
| 3528 | ColorTree tree; |
| 3529 | size_t numpixels = (size_t)w * (size_t)h; |
| 3530 | unsigned error = 0; |
| 3531 | |
| 3532 | if(mode_in->colortype == LCT_PALETTE && !mode_in->palette) { |
| 3533 | return 107; /* error: must provide palette if input mode is palette */ |
| 3534 | } |
| 3535 | |
| 3536 | if(lodepng_color_mode_equal(mode_out, mode_in)) { |
| 3537 | size_t numbytes = lodepng_get_raw_size(w, h, mode_in); |
| 3538 | lodepng_memcpy(out, in, numbytes); |
| 3539 | return 0; |
| 3540 | } |
| 3541 | |
| 3542 | if(mode_out->colortype == LCT_PALETTE) { |
| 3543 | size_t palettesize = mode_out->palettesize; |
| 3544 | const unsigned char* palette = mode_out->palette; |
| 3545 | size_t palsize = (size_t)1u << mode_out->bitdepth; |
| 3546 | /*if the user specified output palette but did not give the values, assume |
| 3547 | they want the values of the input color type (assuming that one is palette). |
| 3548 | Note that we never create a new palette ourselves.*/ |
| 3549 | if(palettesize == 0) { |
| 3550 | palettesize = mode_in->palettesize; |
| 3551 | palette = mode_in->palette; |
| 3552 | /*if the input was also palette with same bitdepth, then the color types are also |
| 3553 | equal, so copy literally. This to preserve the exact indices that were in the PNG |
| 3554 | even in case there are duplicate colors in the palette.*/ |
| 3555 | if(mode_in->colortype == LCT_PALETTE && mode_in->bitdepth == mode_out->bitdepth) { |
| 3556 | size_t numbytes = lodepng_get_raw_size(w, h, mode_in); |
| 3557 | lodepng_memcpy(out, in, numbytes); |
| 3558 | return 0; |
| 3559 | } |
| 3560 | } |
| 3561 | if(palettesize < palsize) palsize = palettesize; |
| 3562 | color_tree_init(&tree); |
| 3563 | for(i = 0; i != palsize; ++i) { |
| 3564 | const unsigned char* p = &palette[i * 4]; |
| 3565 | error = color_tree_add(&tree, p[0], p[1], p[2], p[3], (unsigned)i); |
| 3566 | if(error) break; |
| 3567 | } |
| 3568 | } |
| 3569 | |
| 3570 | if(!error) { |
| 3571 | if(mode_in->bitdepth == 16 && mode_out->bitdepth == 16) { |
| 3572 | for(i = 0; i != numpixels; ++i) { |
| 3573 | unsigned short r = 0, g = 0, b = 0, a = 0; |
| 3574 | getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); |
| 3575 | rgba16ToPixel(out, i, mode_out, r, g, b, a); |
| 3576 | } |
| 3577 | } else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA) { |
| 3578 | getPixelColorsRGBA8(out, numpixels, in, mode_in); |
| 3579 | } else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB) { |
| 3580 | getPixelColorsRGB8(out, numpixels, in, mode_in); |
| 3581 | } else { |
no test coverage detected