1 /* 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 12 /**************************************************************************** 13 * 14 * Module Title : gen_scalers.c 15 * 16 * Description : Generic image scaling functions. 17 * 18 ***************************************************************************/ 19 20 /**************************************************************************** 21 * Header Files 22 ****************************************************************************/ 23 #include "vpx_scale/vpxscale.h" 24 25 /**************************************************************************** 26 * Imports 27 ****************************************************************************/ 28 29 /**************************************************************************** 30 * 31 * ROUTINE : vp8cx_horizontal_line_4_5_scale_c 32 * 33 * INPUTS : const unsigned char *source : Pointer to source data. 34 * unsigned int source_width : Stride of source. 35 * unsigned char *dest : Pointer to destination data. 36 * unsigned int dest_width : Stride of destination (NOT USED). 37 * 38 * OUTPUTS : None. 39 * 40 * RETURNS : void 41 * 42 * FUNCTION : Copies horizontal line of pixels from source to 43 * destination scaling up by 4 to 5. 44 * 45 * SPECIAL NOTES : None. 46 * 47 ****************************************************************************/ 48 static 49 void vp8cx_horizontal_line_4_5_scale_c 50 ( 51 const unsigned char *source, 52 unsigned int source_width, 53 unsigned char *dest, 54 unsigned int dest_width 55 ) 56 { 57 unsigned i; 58 unsigned int a, b, c; 59 unsigned char *des = dest; 60 const unsigned char *src = source; 61 62 (void) dest_width; 63 64 for (i = 0; i < source_width - 4; i += 4) 65 { 66 a = src[0]; 67 b = src[1]; 68 des [0] = (unsigned char) a; 69 des [1] = (unsigned char)((a * 51 + 205 * b + 128) >> 8); 70 c = src[2] * 154; 71 a = src[3]; 72 des [2] = (unsigned char)((b * 102 + c + 128) >> 8); 73 des [3] = (unsigned char)((c + 102 * a + 128) >> 8); 74 b = src[4]; 75 des [4] = (unsigned char)((a * 205 + 51 * b + 128) >> 8); 76 77 src += 4; 78 des += 5; 79 } 80 81 a = src[0]; 82 b = src[1]; 83 des [0] = (unsigned char)(a); 84 des [1] = (unsigned char)((a * 51 + 205 * b + 128) >> 8); 85 c = src[2] * 154; 86 a = src[3]; 87 des [2] = (unsigned char)((b * 102 + c + 128) >> 8); 88 des [3] = (unsigned char)((c + 102 * a + 128) >> 8); 89 des [4] = (unsigned char)(a); 90 91 } 92 93 /**************************************************************************** 94 * 95 * ROUTINE : vp8cx_vertical_band_4_5_scale_c 96 * 97 * INPUTS : unsigned char *dest : Pointer to destination data. 98 * unsigned int dest_pitch : Stride of destination data. 99 * unsigned int dest_width : Width of destination data. 100 * 101 * OUTPUTS : None. 102 * 103 * RETURNS : void 104 * 105 * FUNCTION : Scales vertical band of pixels by scale 4 to 5. The 106 * height of the band scaled is 4-pixels. 107 * 108 * SPECIAL NOTES : The routine uses the first line of the band below 109 * the current band. 110 * 111 ****************************************************************************/ 112 static 113 void vp8cx_vertical_band_4_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) 114 { 115 unsigned int i; 116 unsigned int a, b, c, d; 117 unsigned char *des = dest; 118 119 for (i = 0; i < dest_width; i++) 120 { 121 a = des [0]; 122 b = des [dest_pitch]; 123 124 des[dest_pitch] = (unsigned char)((a * 51 + 205 * b + 128) >> 8); 125 126 c = des[dest_pitch*2] * 154; 127 d = des[dest_pitch*3]; 128 129 des [dest_pitch*2] = (unsigned char)((b * 102 + c + 128) >> 8); 130 des [dest_pitch*3] = (unsigned char)((c + 102 * d + 128) >> 8); 131 132 // First line in next band 133 a = des [dest_pitch * 5]; 134 des [dest_pitch * 4] = (unsigned char)((d * 205 + 51 * a + 128) >> 8); 135 136 des ++; 137 } 138 } 139 140 /**************************************************************************** 141 * 142 * ROUTINE : vp8cx_last_vertical_band_4_5_scale_c 143 * 144 * INPUTS : unsigned char *dest : Pointer to destination data. 145 * unsigned int dest_pitch : Stride of destination data. 146 * unsigned int dest_width : Width of destination data. 147 * 148 * OUTPUTS : None. 149 * 150 * RETURNS : void 151 * 152 * FUNCTION : Scales last vertical band of pixels by scale 4 to 5. The 153 * height of the band scaled is 4-pixels. 154 * 155 * SPECIAL NOTES : The routine does not have available the first line of 156 * the band below the current band, since this is the 157 * last band. 158 * 159 ****************************************************************************/ 160 static 161 void vp8cx_last_vertical_band_4_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) 162 { 163 unsigned int i; 164 unsigned int a, b, c, d; 165 unsigned char *des = dest; 166 167 for (i = 0; i < dest_width; ++i) 168 { 169 a = des[0]; 170 b = des[dest_pitch]; 171 172 des[dest_pitch] = (unsigned char)((a * 51 + 205 * b + 128) >> 8); 173 174 c = des[dest_pitch*2] * 154; 175 d = des[dest_pitch*3]; 176 177 des [dest_pitch*2] = (unsigned char)((b * 102 + c + 128) >> 8); 178 des [dest_pitch*3] = (unsigned char)((c + 102 * d + 128) >> 8); 179 180 // No other line for interplation of this line, so .. 181 des[dest_pitch*4] = (unsigned char) d; 182 183 des++; 184 } 185 } 186 187 /**************************************************************************** 188 * 189 * ROUTINE : vp8cx_horizontal_line_3_5_scale_c 190 * 191 * INPUTS : const unsigned char *source : Pointer to source data. 192 * unsigned int source_width : Stride of source. 193 * unsigned char *dest : Pointer to destination data. 194 * unsigned int dest_width : Stride of destination (NOT USED). 195 * 196 * OUTPUTS : None. 197 * 198 * RETURNS : void 199 * 200 * FUNCTION : Copies horizontal line of pixels from source to 201 * destination scaling up by 3 to 5. 202 * 203 * SPECIAL NOTES : None. 204 * 205 * 206 ****************************************************************************/ 207 static 208 void vp8cx_horizontal_line_3_5_scale_c 209 ( 210 const unsigned char *source, 211 unsigned int source_width, 212 unsigned char *dest, 213 unsigned int dest_width 214 ) 215 { 216 unsigned int i; 217 unsigned int a, b, c; 218 unsigned char *des = dest; 219 const unsigned char *src = source; 220 221 (void) dest_width; 222 223 for (i = 0; i < source_width - 3; i += 3) 224 { 225 a = src[0]; 226 b = src[1]; 227 des [0] = (unsigned char)(a); 228 des [1] = (unsigned char)((a * 102 + 154 * b + 128) >> 8); 229 230 c = src[2] ; 231 des [2] = (unsigned char)((b * 205 + c * 51 + 128) >> 8); 232 des [3] = (unsigned char)((b * 51 + c * 205 + 128) >> 8); 233 234 a = src[3]; 235 des [4] = (unsigned char)((c * 154 + a * 102 + 128) >> 8); 236 237 src += 3; 238 des += 5; 239 } 240 241 a = src[0]; 242 b = src[1]; 243 des [0] = (unsigned char)(a); 244 245 des [1] = (unsigned char)((a * 102 + 154 * b + 128) >> 8); 246 c = src[2] ; 247 des [2] = (unsigned char)((b * 205 + c * 51 + 128) >> 8); 248 des [3] = (unsigned char)((b * 51 + c * 205 + 128) >> 8); 249 250 des [4] = (unsigned char)(c); 251 } 252 253 /**************************************************************************** 254 * 255 * ROUTINE : vp8cx_vertical_band_3_5_scale_c 256 * 257 * INPUTS : unsigned char *dest : Pointer to destination data. 258 * unsigned int dest_pitch : Stride of destination data. 259 * unsigned int dest_width : Width of destination data. 260 * 261 * OUTPUTS : None. 262 * 263 * RETURNS : void 264 * 265 * FUNCTION : Scales vertical band of pixels by scale 3 to 5. The 266 * height of the band scaled is 3-pixels. 267 * 268 * SPECIAL NOTES : The routine uses the first line of the band below 269 * the current band. 270 * 271 ****************************************************************************/ 272 static 273 void vp8cx_vertical_band_3_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) 274 { 275 unsigned int i; 276 unsigned int a, b, c; 277 unsigned char *des = dest; 278 279 for (i = 0; i < dest_width; i++) 280 { 281 a = des [0]; 282 b = des [dest_pitch]; 283 des [dest_pitch] = (unsigned char)((a * 102 + 154 * b + 128) >> 8); 284 285 c = des[dest_pitch*2]; 286 des [dest_pitch*2] = (unsigned char)((b * 205 + c * 51 + 128) >> 8); 287 des [dest_pitch*3] = (unsigned char)((b * 51 + c * 205 + 128) >> 8); 288 289 // First line in next band... 290 a = des [dest_pitch * 5]; 291 des [dest_pitch * 4] = (unsigned char)((c * 154 + a * 102 + 128) >> 8); 292 293 des++; 294 } 295 } 296 297 /**************************************************************************** 298 * 299 * ROUTINE : vp8cx_last_vertical_band_3_5_scale_c 300 * 301 * INPUTS : unsigned char *dest : Pointer to destination data. 302 * unsigned int dest_pitch : Stride of destination data. 303 * unsigned int dest_width : Width of destination data. 304 * 305 * OUTPUTS : None. 306 * 307 * RETURNS : void 308 * 309 * FUNCTION : Scales last vertical band of pixels by scale 3 to 5. The 310 * height of the band scaled is 3-pixels. 311 * 312 * SPECIAL NOTES : The routine does not have available the first line of 313 * the band below the current band, since this is the 314 * last band. 315 * 316 ****************************************************************************/ 317 static 318 void vp8cx_last_vertical_band_3_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) 319 { 320 unsigned int i; 321 unsigned int a, b, c; 322 unsigned char *des = dest; 323 324 for (i = 0; i < dest_width; ++i) 325 { 326 a = des [0]; 327 b = des [dest_pitch]; 328 329 des [ dest_pitch ] = (unsigned char)((a * 102 + 154 * b + 128) >> 8); 330 331 c = des[dest_pitch*2]; 332 des [dest_pitch*2] = (unsigned char)((b * 205 + c * 51 + 128) >> 8); 333 des [dest_pitch*3] = (unsigned char)((b * 51 + c * 205 + 128) >> 8); 334 335 // No other line for interplation of this line, so .. 336 des [ dest_pitch * 4 ] = (unsigned char)(c) ; 337 338 des++; 339 } 340 } 341 342 /**************************************************************************** 343 * 344 * ROUTINE : vp8cx_horizontal_line_1_2_scale_c 345 * 346 * INPUTS : const unsigned char *source : Pointer to source data. 347 * unsigned int source_width : Stride of source. 348 * unsigned char *dest : Pointer to destination data. 349 * unsigned int dest_width : Stride of destination (NOT USED). 350 * 351 * OUTPUTS : None. 352 * 353 * RETURNS : void 354 * 355 * FUNCTION : Copies horizontal line of pixels from source to 356 * destination scaling up by 1 to 2. 357 * 358 * SPECIAL NOTES : None. 359 * 360 ****************************************************************************/ 361 static 362 void vp8cx_horizontal_line_1_2_scale_c 363 ( 364 const unsigned char *source, 365 unsigned int source_width, 366 unsigned char *dest, 367 unsigned int dest_width 368 ) 369 { 370 unsigned int i; 371 unsigned int a, b; 372 unsigned char *des = dest; 373 const unsigned char *src = source; 374 375 (void) dest_width; 376 377 for (i = 0; i < source_width - 1; i += 1) 378 { 379 a = src[0]; 380 b = src[1]; 381 des [0] = (unsigned char)(a); 382 des [1] = (unsigned char)((a + b + 1) >> 1); 383 src += 1; 384 des += 2; 385 } 386 387 a = src[0]; 388 des [0] = (unsigned char)(a); 389 des [1] = (unsigned char)(a); 390 } 391 392 /**************************************************************************** 393 * 394 * ROUTINE : vp8cx_vertical_band_1_2_scale_c 395 * 396 * INPUTS : unsigned char *dest : Pointer to destination data. 397 * unsigned int dest_pitch : Stride of destination data. 398 * unsigned int dest_width : Width of destination data. 399 * 400 * OUTPUTS : None. 401 * 402 * RETURNS : void 403 * 404 * FUNCTION : Scales vertical band of pixels by scale 1 to 2. The 405 * height of the band scaled is 1-pixel. 406 * 407 * SPECIAL NOTES : The routine uses the first line of the band below 408 * the current band. 409 * 410 ****************************************************************************/ 411 static 412 void vp8cx_vertical_band_1_2_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) 413 { 414 unsigned int i; 415 unsigned int a, b; 416 unsigned char *des = dest; 417 418 for (i = 0; i < dest_width; i++) 419 { 420 a = des [0]; 421 b = des [dest_pitch * 2]; 422 423 des[dest_pitch] = (unsigned char)((a + b + 1) >> 1); 424 425 des++; 426 } 427 } 428 429 /**************************************************************************** 430 * 431 * ROUTINE : vp8cx_last_vertical_band_1_2_scale_c 432 * 433 * INPUTS : unsigned char *dest : Pointer to destination data. 434 * unsigned int dest_pitch : Stride of destination data. 435 * unsigned int dest_width : Width of destination data. 436 * 437 * OUTPUTS : None. 438 * 439 * RETURNS : void 440 * 441 * FUNCTION : Scales last vertical band of pixels by scale 1 to 2. The 442 * height of the band scaled is 1-pixel. 443 * 444 * SPECIAL NOTES : The routine does not have available the first line of 445 * the band below the current band, since this is the 446 * last band. 447 * 448 ****************************************************************************/ 449 static 450 void vp8cx_last_vertical_band_1_2_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) 451 { 452 unsigned int i; 453 unsigned char *des = dest; 454 455 for (i = 0; i < dest_width; ++i) 456 { 457 des[dest_pitch] = des[0]; 458 des++; 459 } 460 } 461 462 #include "vpx_scale/vpxscale.h" 463 #include "vpx_mem/vpx_mem.h" 464 465 struct vpxglobal_scalling_ptrs_t *g_scaling_ptrs = 0; 466 467 int 468 register_generic_scalers(void) 469 { 470 int rv = 0; 471 472 g_scaling_ptrs = (struct vpxglobal_scalling_ptrs_t *)vpx_malloc(sizeof(struct vpxglobal_scalling_ptrs_t)); 473 474 if (g_scaling_ptrs) 475 { 476 g_scaling_ptrs->vpxhorizontal_line_1_2_scale_t = vp8cx_horizontal_line_1_2_scale_c; 477 g_scaling_ptrs->vpxvertical_band_1_2_scale_t = vp8cx_vertical_band_1_2_scale_c; 478 g_scaling_ptrs->vpxlast_vertical_band_1_2_scale_t = vp8cx_last_vertical_band_1_2_scale_c; 479 g_scaling_ptrs->vpxhorizontal_line_3_5_scale_t = vp8cx_horizontal_line_3_5_scale_c; 480 g_scaling_ptrs->vpxvertical_band_3_5_scale_t = vp8cx_vertical_band_3_5_scale_c; 481 g_scaling_ptrs->vpxlast_vertical_band_3_5_scale_t = vp8cx_last_vertical_band_3_5_scale_c; 482 g_scaling_ptrs->vpxhorizontal_line_4_5_scale_t = vp8cx_horizontal_line_4_5_scale_c; 483 g_scaling_ptrs->vpxvertical_band_4_5_scale_t = vp8cx_vertical_band_4_5_scale_c; 484 g_scaling_ptrs->vpxlast_vertical_band_4_5_scale_t = vp8cx_last_vertical_band_4_5_scale_c; 485 } 486 else 487 { 488 rv = -1; 489 } 490 491 /* 492 vp8_horizontal_line_1_2_scale = vp8cx_horizontal_line_1_2_scale_c; 493 vp8_vertical_band_1_2_scale = vp8cx_vertical_band_1_2_scale_c; 494 vp8_last_vertical_band_1_2_scale = vp8cx_last_vertical_band_1_2_scale_c; 495 vp8_horizontal_line_3_5_scale = vp8cx_horizontal_line_3_5_scale_c; 496 vp8_vertical_band_3_5_scale = vp8cx_vertical_band_3_5_scale_c; 497 vp8_last_vertical_band_3_5_scale = vp8cx_last_vertical_band_3_5_scale_c; 498 vp8_horizontal_line_4_5_scale = vp8cx_horizontal_line_4_5_scale_c; 499 vp8_vertical_band_4_5_scale = vp8cx_vertical_band_4_5_scale_c; 500 vp8_last_vertical_band_4_5_scale = vp8cx_last_vertical_band_4_5_scale_c; 501 */ 502 503 return rv; 504 } 505 506 int 507 de_register_generic_scalers(void) 508 { 509 int rv = 0; 510 511 if (g_scaling_ptrs) 512 { 513 vpx_free(g_scaling_ptrs); 514 g_scaling_ptrs = 0; 515 } 516 else 517 { 518 rv = -1; 519 } 520 521 return rv; 522 } 523