@@ -39,7 +39,7 @@ extern "C"
3939{
4040#include < png.h>
4141}
42-
42+ # include < set >
4343#pragma GCC diagnostic pop
4444
4545#define MAX_OCTREE_LEVELS 4
@@ -515,42 +515,42 @@ void save_as_png8_oct(T1 & file,
515515 }
516516
517517 // transparency values per palette index
518- std::vector<unsigned > alphaTable ;
519- // alphaTable .resize(palette.size());//allow semitransparency also in almost opaque range
518+ std::vector<unsigned > alpha_table ;
519+ // alpha_table .resize(palette.size());//allow semitransparency also in almost opaque range
520520 if (opts.trans_mode != 0 )
521521 {
522- alphaTable .resize (palette.size () - cols[TRANSPARENCY_LEVELS-1 ]);
522+ alpha_table .resize (palette.size () - cols[TRANSPARENCY_LEVELS-1 ]);
523523 }
524524
525525 if (palette.size () > 16 )
526526 {
527527 // >16 && <=256 colors -> write 8-bit color depth
528528 image_gray8 reduced_image (width,height);
529- reduce_8 (image, reduced_image, trees, limits, TRANSPARENCY_LEVELS, alphaTable );
530- save_as_png (file,palette,reduced_image,width,height,8 ,alphaTable ,opts);
529+ reduce_8 (image, reduced_image, trees, limits, TRANSPARENCY_LEVELS, alpha_table );
530+ save_as_png (file,palette,reduced_image,width,height,8 ,alpha_table ,opts);
531531 }
532532 else if (palette.size () == 1 )
533533 {
534534 // 1 color image -> write 1-bit color depth PNG
535535 unsigned image_width = ((width + 15 ) >> 3 ) & ~1U ; // 1-bit image, round up to 16-bit boundary
536536 unsigned image_height = height;
537537 image_gray8 reduced_image (image_width,image_height);
538- reduce_1 (image,reduced_image,trees, limits, alphaTable );
538+ reduce_1 (image,reduced_image,trees, limits, alpha_table );
539539 if (meanAlpha<255 && cols[0 ]==0 )
540540 {
541- alphaTable .resize (1 );
542- alphaTable [0 ] = meanAlpha;
541+ alpha_table .resize (1 );
542+ alpha_table [0 ] = meanAlpha;
543543 }
544- save_as_png (file,palette,reduced_image,width,height,1 ,alphaTable ,opts);
544+ save_as_png (file,palette,reduced_image,width,height,1 ,alpha_table ,opts);
545545 }
546546 else
547547 {
548548 // <=16 colors -> write 4-bit color depth PNG
549549 unsigned image_width = ((width + 7 ) >> 1 ) & ~3U ; // 4-bit image, round up to 32-bit boundary
550550 unsigned image_height = height;
551551 image_gray8 reduced_image (image_width,image_height);
552- reduce_4 (image, reduced_image, trees, limits, TRANSPARENCY_LEVELS, alphaTable );
553- save_as_png (file,palette,reduced_image,width,height,4 ,alphaTable ,opts);
552+ reduce_4 (image, reduced_image, trees, limits, TRANSPARENCY_LEVELS, alpha_table );
553+ save_as_png (file,palette,reduced_image,width,height,4 ,alpha_table ,opts);
554554 }
555555}
556556
@@ -560,7 +560,7 @@ void save_as_png8(T1 & file,
560560 T2 const & image,
561561 T3 const & tree,
562562 std::vector<mapnik::rgb> const & palette,
563- std::vector<unsigned > const & alphaTable ,
563+ std::vector<unsigned > const & alpha_table ,
564564 png_options const & opts)
565565{
566566 unsigned width = image.width ();
@@ -579,7 +579,7 @@ void save_as_png8(T1 & file,
579579 row_out[x] = tree.quantize (row[x]);
580580 }
581581 }
582- save_as_png (file, palette, reduced_image, width, height, 8 , alphaTable , opts);
582+ save_as_png (file, palette, reduced_image, width, height, 8 , alpha_table , opts);
583583 }
584584 else if (palette.size () == 1 )
585585 {
@@ -588,7 +588,7 @@ void save_as_png8(T1 & file,
588588 unsigned image_height = height;
589589 image_gray8 reduced_image (image_width, image_height);
590590 reduced_image.set (0 );
591- save_as_png (file, palette, reduced_image, width, height, 1 , alphaTable , opts);
591+ save_as_png (file, palette, reduced_image, width, height, 1 , alpha_table , opts);
592592 }
593593 else
594594 {
@@ -612,7 +612,7 @@ void save_as_png8(T1 & file,
612612 row_out[x>>1 ] |= index;
613613 }
614614 }
615- save_as_png (file, palette, reduced_image, width, height, 4 , alphaTable , opts);
615+ save_as_png (file, palette, reduced_image, width, height, 4 , alpha_table , opts);
616616 }
617617}
618618
@@ -623,6 +623,7 @@ void save_as_png8_hex(T1 & file,
623623{
624624 unsigned width = image.width ();
625625 unsigned height = image.height ();
626+
626627 if (width + height > 3 ) // at least 3 pixels (hextree implementation requirement)
627628 {
628629 // structure for color quantization
@@ -647,20 +648,44 @@ void save_as_png8_hex(T1 & file,
647648 }
648649
649650 // transparency values per palette index
650- std::vector<mapnik::rgba> pal;
651- tree.create_palette (pal);
651+ std::vector<mapnik::rgba> rgba_palette;
652+ tree.create_palette (rgba_palette);
653+ auto size = rgba_palette.size ();
652654 std::vector<mapnik::rgb> palette;
653- std::vector<unsigned > alphaTable;
654- for (unsigned i=0 ; i<pal.size (); ++i)
655+ std::vector<unsigned > alpha_table;
656+ palette.reserve (size);
657+ alpha_table.reserve (size);
658+ for (auto const & c : rgba_palette)
655659 {
656- palette.push_back ( rgb (pal[i] .r , pal[i] .g , pal[i]. b ) );
657- alphaTable .push_back (pal[i] .a );
660+ palette.emplace_back (c .r , c .g , c. b );
661+ alpha_table .push_back (c .a );
658662 }
659- save_as_png8<T1, T2, hextree<mapnik::rgba> >(file, image, tree, palette, alphaTable , opts);
663+ save_as_png8<T1, T2, hextree<mapnik::rgba> >(file, image, tree, palette, alpha_table , opts);
660664 }
661665 else
662666 {
663- throw std::runtime_error (" Can't quantize images with less than 3 pixels" );
667+
668+ std::set<mapnik::rgba> colors;
669+ for (unsigned y = 0 ; y < height; ++y)
670+ {
671+ typename T2::pixel_type const * row = image.get_row (y);
672+
673+ for (unsigned x = 0 ; x < width; ++x)
674+ {
675+ unsigned val = row[x];
676+ colors.emplace (U2RED (val), U2GREEN (val), U2BLUE (val), U2ALPHA (val));
677+ }
678+ }
679+ std::string str;
680+ for (auto c : colors)
681+ {
682+ str.push_back (c.r );
683+ str.push_back (c.g );
684+ str.push_back (c.b );
685+ str.push_back (c.a );
686+ }
687+ rgba_palette pal (str, rgba_palette::PALETTE_RGBA);
688+ save_as_png8<T1, T2, rgba_palette>(file, image, pal, pal.palette (), pal.alpha_table (), opts);
664689 }
665690}
666691
@@ -670,7 +695,7 @@ void save_as_png8_pal(T1 & file,
670695 rgba_palette const & pal,
671696 png_options const & opts)
672697{
673- save_as_png8<T1, T2, rgba_palette>(file, image, pal, pal.palette (), pal.alphaTable (), opts);
698+ save_as_png8<T1, T2, rgba_palette>(file, image, pal, pal.palette (), pal.alpha_table (), opts);
674699}
675700
676701}
0 commit comments