| | 275 | template <typename Image> |
| | 276 | inline void scale_image_bilinear (Image& target,const Image& source) |
| | 277 | { |
| | 278 | |
| | 279 | int source_width=source.width(); |
| | 280 | int source_height=source.height(); |
| | 281 | |
| | 282 | int target_width=target.width(); |
| | 283 | int target_height=target.height(); |
| | 284 | |
| | 285 | if (source_width<1 || source_height<1 || |
| | 286 | target_width<1 || target_height<1) return; |
| | 287 | int x=0,y=0,xs=0,ys=0; |
| | 288 | int tw2 = target_width/2; |
| | 289 | int th2 = target_height/2; |
| | 290 | |
| | 291 | |
| | 292 | for (y=0;y<target_height;++y) |
| | 293 | { |
| | 294 | ys = y*source_height/target_height; |
| | 295 | int ys1 = ys+1; |
| | 296 | if (ys1>=source_height) |
| | 297 | ys1--; |
| | 298 | unsigned yprt = y*source_height%target_height; |
| | 299 | unsigned yprt1 = target_height-yprt; |
| | 300 | for (x=0;x<target_width;++x) |
| | 301 | { |
| | 302 | xs = x*source_width/target_width; |
| | 303 | if (source_width>=target_width || source_height>=target_height){ |
| | 304 | target(x,y)=source(xs,ys); |
| | 305 | continue; |
| | 306 | } |
| | 307 | unsigned xprt = x*source_width%target_width; |
| | 308 | unsigned xprt1 = target_width-xprt; |
| | 309 | int xs1 = xs+1; |
| | 310 | if (xs1>=source_width) |
| | 311 | xs1--; |
| | 312 | |
| | 313 | unsigned a = source(xs,ys); |
| | 314 | unsigned b = source(xs1,ys); |
| | 315 | unsigned c = source(xs,ys1); |
| | 316 | unsigned d = source(xs1,ys1); |
| | 317 | unsigned out=0; |
| | 318 | unsigned t = 0; |
| | 319 | |
| | 320 | for(int i=0; i<4; i++){ |
| | 321 | unsigned p,r,s; |
| | 322 | // X axis |
| | 323 | p = a&0xff; |
| | 324 | r = b&0xff; |
| | 325 | if (p!=r) |
| | 326 | r = (r*xprt+p*xprt1+tw2)/target_width; |
| | 327 | p = c&0xff; |
| | 328 | s = d&0xff; |
| | 329 | if (p!=s) |
| | 330 | s = (s*xprt+p*xprt1+tw2)/target_width; |
| | 331 | // Y axis |
| | 332 | if (r!=s) |
| | 333 | r = (s*yprt+r*yprt1+th2)/target_height; |
| | 334 | // channel up |
| | 335 | out |= r << t; |
| | 336 | t += 8; |
| | 337 | a >>= 8; |
| | 338 | b >>= 8; |
| | 339 | c >>= 8; |
| | 340 | d >>= 8; |
| | 341 | } |
| | 342 | target(x,y)=out; |
| | 343 | } |
| | 344 | } |
| | 345 | } |
| | 346 | |
| | 347 | template <typename Image> |
| | 348 | inline void scale_image_bilinear8 (Image& target,const Image& source) |
| | 349 | { |
| | 350 | |
| | 351 | int source_width=source.width(); |
| | 352 | int source_height=source.height(); |
| | 353 | |
| | 354 | int target_width=target.width(); |
| | 355 | int target_height=target.height(); |
| | 356 | |
| | 357 | if (source_width<1 || source_height<1 || |
| | 358 | target_width<1 || target_height<1) return; |
| | 359 | int x=0,y=0,xs=0,ys=0; |
| | 360 | int tw2 = target_width/2; |
| | 361 | int th2 = target_height/2; |
| | 362 | |
| | 363 | |
| | 364 | for (y=0;y<target_height;++y) |
| | 365 | { |
| | 366 | ys = y*source_height/target_height; |
| | 367 | int ys1 = ys+1; |
| | 368 | if (ys1>=source_height) |
| | 369 | ys1--; |
| | 370 | unsigned yprt = y*source_height%target_height; |
| | 371 | unsigned yprt1 = target_height-yprt; |
| | 372 | for (x=0;x<target_width;++x) |
| | 373 | { |
| | 374 | xs = x*source_width/target_width; |
| | 375 | if (source_width>=target_width || source_height>=target_height){ |
| | 376 | target(x,y)=source(xs,ys); |
| | 377 | continue; |
| | 378 | } |
| | 379 | unsigned xprt = x*source_width%target_width; |
| | 380 | unsigned xprt1 = target_width-xprt; |
| | 381 | int xs1 = xs+1; |
| | 382 | if (xs1>=source_width) |
| | 383 | xs1--; |
| | 384 | |
| | 385 | unsigned a = source(xs,ys); |
| | 386 | unsigned b = source(xs1,ys); |
| | 387 | unsigned c = source(xs,ys1); |
| | 388 | unsigned d = source(xs1,ys1); |
| | 389 | unsigned p,r,s; |
| | 390 | // X axis |
| | 391 | p = a&0xff; |
| | 392 | r = b&0xff; |
| | 393 | if (p!=r) |
| | 394 | r = (r*xprt+p*xprt1+tw2)/target_width; |
| | 395 | p = c&0xff; |
| | 396 | s = d&0xff; |
| | 397 | if (p!=s) |
| | 398 | s = (s*xprt+p*xprt1+tw2)/target_width; |
| | 399 | // Y axis |
| | 400 | if (r!=s) |
| | 401 | r = (s*yprt+r*yprt1+th2)/target_height; |
| | 402 | target(x,y)=(0xff<<24) | (r<<16) | (r<<8) | r; |
| | 403 | } |
| | 404 | } |
| | 405 | } |
| | 406 | |