~ubuntu-branches/ubuntu/trusty/mapnik/trusty-proposed

« back to all changes in this revision

Viewing changes to include/mapnik/png_io.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Sauthier
  • Date: 2009-08-27 00:28:37 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090827002837-ztqzfg2rmclfh4i9
Tags: 0.6.1-0ubuntu1
* New upstream release.
* Change usr/lib to usr/lib* to enable build on 64 bits systems due to new
  configuration in SConstruct in :
  - debian/libmapnik-dev.install
  - debian/libmapnik0.6.install
  - debian/mapnik-plugin-base

Show diffs side-by-side

added added

removed removed

Lines of Context:
103
103
            unsigned val = row[x];
104
104
            mapnik::rgb c((val)&0xff, (val>>8)&0xff, (val>>16) & 0xff);
105
105
            byte index = tree.quantize(c);
 
106
            if (!((val>>24)&0x80)) index = 0;//alfa
106
107
            row_out[x] = index;
107
108
         }
108
109
      }
109
110
   }
110
 
         
 
111
 
111
112
   template <typename T>
112
113
   void reduce_4 (T const& in, ImageData8 & out, octree<rgb> & tree)
113
114
   {
114
115
      unsigned width = in.width();
115
116
      unsigned height = in.height();
116
 
      
 
117
 
117
118
      for (unsigned y = 0; y < height; ++y)
118
119
      {
119
120
         mapnik::ImageData32::pixel_type const * row = in.getRow(y);
120
121
         mapnik::ImageData8::pixel_type  * row_out = out.getRow(y);
121
 
         
 
122
 
122
123
         for (unsigned x = 0; x < width; ++x)
123
124
         {
124
125
            unsigned val = row[x];
125
126
            mapnik::rgb c((val)&0xff, (val>>8)&0xff, (val>>16) & 0xff);
126
127
            byte index = tree.quantize(c);
127
128
            if (x%2 >  0) index = index<<4;
128
 
            row_out[x>>1] |= index;  
 
129
            if (!((val>>24)&0x80)) index = 0;//alfa
 
130
            row_out[x>>1] |= index;
129
131
         }
130
132
      }
131
133
   }
132
 
   
 
134
 
133
135
   // 1-bit but only one color.
134
136
   template <typename T>
135
137
   void reduce_1(T const&, ImageData8 & out, octree<rgb> &)
136
138
   {
137
139
      out.set(0); // only one color!!!
138
 
   }  
139
 
   
 
140
   }
 
141
 
140
142
   template <typename T>
141
 
   void save_as_png(T & file, std::vector<mapnik::rgb> & palette, 
142
 
                    mapnik::ImageData8 const& image, 
 
143
   void save_as_png(T & file, std::vector<mapnik::rgb> & palette,
 
144
                    mapnik::ImageData8 const& image,
143
145
                    unsigned width,
144
146
                    unsigned height,
145
 
                    unsigned color_depth)
146
 
   {        
 
147
                    unsigned color_depth,
 
148
                    bool hasAlfa)
 
149
   {
147
150
      png_voidp error_ptr=0;
148
151
      png_structp png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING,
149
152
                                                  error_ptr,0, 0);
150
 
      
 
153
 
151
154
      if (!png_ptr) return;
152
 
   
 
155
 
153
156
      // switch on optimization only if supported
154
157
#if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) && defined(PNG_MMX_CODE_SUPPORTED)
155
158
      png_uint_32 mask, flags;
170
173
         return;
171
174
      }
172
175
      png_set_write_fn (png_ptr, &file, &write_data<T>, &flush_data<T>);
173
 
          
 
176
 
174
177
      png_set_IHDR(png_ptr, info_ptr,width,height,color_depth,
175
178
                   PNG_COLOR_TYPE_PALETTE,PNG_INTERLACE_NONE,
176
179
                   PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
177
180
 
178
181
      png_set_PLTE(png_ptr,info_ptr,reinterpret_cast<png_color*>(&palette[0]),palette.size());
179
 
      
 
182
 
 
183
      // make transparent lowest indexes, so tRNS is small
 
184
      if (hasAlfa)
 
185
      {
 
186
         byte trans[] = {0,0,0,0};
 
187
         //png_color_16p unused;
 
188
         png_set_tRNS(png_ptr, info_ptr, (png_bytep)trans, 1, NULL);
 
189
      }
 
190
 
180
191
      png_write_info(png_ptr, info_ptr);
181
192
      for (unsigned i=0;i<height;i++)
182
193
      {
183
194
         png_write_row(png_ptr,(png_bytep)image.getRow(i));
184
195
      }
185
 
   
 
196
 
186
197
      png_write_end(png_ptr, info_ptr);
187
198
      png_destroy_write_struct(&png_ptr, &info_ptr);
188
199
   }
189
 
   
 
200
 
190
201
   template <typename T1,typename T2>
191
202
   void save_as_png256(T1 & file, T2 const& image)
192
203
   {
199
210
         for (unsigned x = 0; x < width; ++x)
200
211
         {
201
212
            unsigned val = row[x];
202
 
            tree.insert(mapnik::rgb((val)&0xff, (val>>8)&0xff, (val>>16) & 0xff));
 
213
            if ((val>>24)&0x80)
 
214
            {
 
215
               tree.insert(mapnik::rgb((val)&0xff, (val>>8)&0xff, (val>>16) & 0xff));
 
216
            }
 
217
            else
 
218
            {
 
219
               tree.hasAlfa(true);
 
220
            }
203
221
         }
204
222
      }
205
 
      
 
223
 
206
224
      std::vector<rgb> palette;
207
225
      tree.create_palette(palette);
208
226
      assert(palette.size() <= 256);
209
 
      
 
227
 
210
228
      if (palette.size() > 16 )
211
229
      {
212
230
         // >16 && <=256 colors -> write 8-bit color depth
213
 
         ImageData8 reduced_image(width,height);   
 
231
         ImageData8 reduced_image(width,height);
214
232
         reduce_8(image,reduced_image,tree);
215
 
         save_as_png(file,palette,reduced_image,width,height,8);         
 
233
         save_as_png(file,palette,reduced_image,width,height,8,tree.hasAlfa());
216
234
      }
217
 
      else if (palette.size() == 1) 
 
235
      else if (palette.size() == 1)
218
236
      {
219
237
         // 1 color image ->  write 1-bit color depth PNG
220
238
         unsigned image_width  = (int(0.125*width) + 7)&~7;
221
239
         unsigned image_height = height;
222
240
         ImageData8 reduced_image(image_width,image_height);
223
 
         reduce_1(image,reduced_image,tree); 
224
 
         save_as_png(file,palette,reduced_image,width,height,1);
 
241
         reduce_1(image,reduced_image,tree);
 
242
         save_as_png(file,palette,reduced_image,width,height,1,tree.hasAlfa());
225
243
      }
226
 
      else 
 
244
      else
227
245
      {
228
246
         // <=16 colors -> write 4-bit color depth PNG
229
247
         unsigned image_width  = (int(0.5*width) + 3)&~3;
230
248
         unsigned image_height = height;
231
249
         ImageData8 reduced_image(image_width,image_height);
232
250
         reduce_4(image,reduced_image,tree);
233
 
         save_as_png(file,palette,reduced_image,width,height,4);
234
 
      }      
 
251
         save_as_png(file,palette,reduced_image,width,height,4,tree.hasAlfa());
 
252
      }
235
253
   }
236
254
}