Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: third_party/libpng/pngwutil.c

Issue 2132783002: Fix png encoding performance regressions - downstream diff (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/libpng/README.chromium ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* pngwutil.c - utilities to write a PNG file 2 /* pngwutil.c - utilities to write a PNG file
3 * 3 *
4 * Last changed in libpng 1.6.22 [May 26, 2016] 4 * Last changed in libpng 1.6.22 [May 26, 2016]
5 * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson 5 * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8 * 8 *
9 * This code is released under the libpng license. 9 * This code is released under the libpng license.
10 * For conditions of distribution and use, see the disclaimer 10 * For conditions of distribution and use, see the disclaimer
(...skipping 2260 matching lines...) Expand 10 before | Expand all | Expand 10 after
2271 v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); 2271 v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
2272 sum += (v < 128) ? v : 256 - v; 2272 sum += (v < 128) ? v : 256 - v;
2273 2273
2274 if (sum > lmins) /* We are already worse, don't continue. */ 2274 if (sum > lmins) /* We are already worse, don't continue. */
2275 break; 2275 break;
2276 } 2276 }
2277 2277
2278 return (sum); 2278 return (sum);
2279 } 2279 }
2280 2280
2281 static void /* PRIVATE */
2282 png_setup_sub_row_only(png_structrp png_ptr, const png_uint_32 bpp,
2283 const png_size_t row_bytes)
2284 {
2285 png_bytep rp, dp, lp;
2286 png_size_t i;
2287
2288 png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
2289
2290 for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp;
2291 i++, rp++, dp++)
2292 {
2293 *dp = *rp;
2294 }
2295
2296 for (lp = png_ptr->row_buf + 1; i < row_bytes;
2297 i++, rp++, lp++, dp++)
2298 {
2299 *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
2300 }
2301 }
2302
2281 static png_size_t /* PRIVATE */ 2303 static png_size_t /* PRIVATE */
2282 png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes, 2304 png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,
2283 const png_size_t lmins) 2305 const png_size_t lmins)
2284 { 2306 {
2285 png_bytep rp, dp, pp; 2307 png_bytep rp, dp, pp;
2286 png_size_t i; 2308 png_size_t i;
2287 png_size_t sum = 0; 2309 png_size_t sum = 0;
2288 int v; 2310 int v;
2289 2311
2290 png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; 2312 png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
2291 2313
2292 for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, 2314 for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
2293 pp = png_ptr->prev_row + 1; i < row_bytes; 2315 pp = png_ptr->prev_row + 1; i < row_bytes;
2294 i++, rp++, pp++, dp++) 2316 i++, rp++, pp++, dp++)
2295 { 2317 {
2296 v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); 2318 v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
2297 sum += (v < 128) ? v : 256 - v; 2319 sum += (v < 128) ? v : 256 - v;
2298 2320
2299 if (sum > lmins) /* We are already worse, don't continue. */ 2321 if (sum > lmins) /* We are already worse, don't continue. */
2300 break; 2322 break;
2301 } 2323 }
2302 2324
2303 return (sum); 2325 return (sum);
2304 } 2326 }
2327 static void /* PRIVATE */
2328 png_setup_up_row_only(png_structrp png_ptr, const png_size_t row_bytes)
2329 {
2330 png_bytep rp, dp, pp;
2331 png_size_t i;
2332
2333 png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
2334
2335 for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
2336 pp = png_ptr->prev_row + 1; i < row_bytes;
2337 i++, rp++, pp++, dp++)
2338 {
2339 *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
2340 }
2341 }
2305 2342
2306 static png_size_t /* PRIVATE */ 2343 static png_size_t /* PRIVATE */
2307 png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp, 2344 png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
2308 const png_size_t row_bytes, const png_size_t lmins) 2345 const png_size_t row_bytes, const png_size_t lmins)
2309 { 2346 {
2310 png_bytep rp, dp, pp, lp; 2347 png_bytep rp, dp, pp, lp;
2311 png_uint_32 i; 2348 png_uint_32 i;
2312 png_size_t sum = 0; 2349 png_size_t sum = 0;
2313 int v; 2350 int v;
2314 2351
(...skipping 13 matching lines...) Expand all
2328 & 0xff); 2365 & 0xff);
2329 2366
2330 sum += (v < 128) ? v : 256 - v; 2367 sum += (v < 128) ? v : 256 - v;
2331 2368
2332 if (sum > lmins) /* We are already worse, don't continue. */ 2369 if (sum > lmins) /* We are already worse, don't continue. */
2333 break; 2370 break;
2334 } 2371 }
2335 2372
2336 return (sum); 2373 return (sum);
2337 } 2374 }
2375 static void /* PRIVATE */
2376 png_setup_avg_row_only(png_structrp png_ptr, const png_uint_32 bpp,
2377 const png_size_t row_bytes)
2378 {
2379 png_bytep rp, dp, pp, lp;
2380 png_uint_32 i;
2381
2382 png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
2383
2384 for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
2385 pp = png_ptr->prev_row + 1; i < bpp; i++)
2386 {
2387 *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
2388 }
2389
2390 for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
2391 {
2392 *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
2393 & 0xff);
2394 }
2395 }
2338 2396
2339 static png_size_t /* PRIVATE */ 2397 static png_size_t /* PRIVATE */
2340 png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp, 2398 png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
2341 const png_size_t row_bytes, const png_size_t lmins) 2399 const png_size_t row_bytes, const png_size_t lmins)
2342 { 2400 {
2343 png_bytep rp, dp, pp, cp, lp; 2401 png_bytep rp, dp, pp, cp, lp;
2344 png_size_t i; 2402 png_size_t i;
2345 png_size_t sum = 0; 2403 png_size_t sum = 0;
2346 int v; 2404 int v;
2347 2405
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2382 v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); 2440 v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
2383 2441
2384 sum += (v < 128) ? v : 256 - v; 2442 sum += (v < 128) ? v : 256 - v;
2385 2443
2386 if (sum > lmins) /* We are already worse, don't continue. */ 2444 if (sum > lmins) /* We are already worse, don't continue. */
2387 break; 2445 break;
2388 } 2446 }
2389 2447
2390 return (sum); 2448 return (sum);
2391 } 2449 }
2450 static void /* PRIVATE */
2451 png_setup_paeth_row_only(png_structrp png_ptr, const png_uint_32 bpp,
2452 const png_size_t row_bytes)
2453 {
2454 png_bytep rp, dp, pp, cp, lp;
2455 png_size_t i;
2456
2457 png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
2458
2459 for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
2460 pp = png_ptr->prev_row + 1; i < bpp; i++)
2461 {
2462 *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
2463 }
2464
2465 for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
2466 i++)
2467 {
2468 int a, b, c, pa, pb, pc, p;
2469
2470 b = *pp++;
2471 c = *cp++;
2472 a = *lp++;
2473
2474 p = b - c;
2475 pc = a - c;
2476
2477 #ifdef PNG_USE_ABS
2478 pa = abs(p);
2479 pb = abs(pc);
2480 pc = abs(p + pc);
2481 #else
2482 pa = p < 0 ? -p : p;
2483 pb = pc < 0 ? -pc : pc;
2484 pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2485 #endif
2486
2487 p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
2488
2489 *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
2490 }
2491 }
2392 #endif /* WRITE_FILTER */ 2492 #endif /* WRITE_FILTER */
2393 2493
2394 void /* PRIVATE */ 2494 void /* PRIVATE */
2395 png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) 2495 png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
2396 { 2496 {
2397 #ifndef PNG_WRITE_FILTER_SUPPORTED 2497 #ifndef PNG_WRITE_FILTER_SUPPORTED
2398 png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1); 2498 png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1);
2399 #else 2499 #else
2400 unsigned int filter_to_do = png_ptr->do_filter; 2500 unsigned int filter_to_do = png_ptr->do_filter;
2401 png_bytep row_buf; 2501 png_bytep row_buf;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2438 */ 2538 */
2439 2539
2440 2540
2441 /* We don't need to test the 'no filter' case if this is the only filter 2541 /* We don't need to test the 'no filter' case if this is the only filter
2442 * that has been chosen, as it doesn't actually do anything to the data. 2542 * that has been chosen, as it doesn't actually do anything to the data.
2443 */ 2543 */
2444 best_row = png_ptr->row_buf; 2544 best_row = png_ptr->row_buf;
2445 2545
2446 if (PNG_SIZE_MAX/128 <= row_bytes) 2546 if (PNG_SIZE_MAX/128 <= row_bytes)
2447 { 2547 {
2448 /* Overflow can occur in the calculation, just select the lowest set 2548 /* Overflow can occur in the calculation, just select the lowest set
2449 * filter. 2549 * filter.
2450 */ 2550 */
2451 filter_to_do &= -filter_to_do; 2551 filter_to_do &= -filter_to_do;
2452 } 2552 }
2453 else if ((filter_to_do & PNG_FILTER_NONE) != 0 && 2553 else if ((filter_to_do & PNG_FILTER_NONE) != 0 &&
2454 filter_to_do != PNG_FILTER_NONE) 2554 filter_to_do != PNG_FILTER_NONE)
2455 { 2555 {
2456 /* Overflow not possible and multiple filters in the list, including the 2556 /* Overflow not possible and multiple filters in the list, including the
2457 * 'none' filter. 2557 * 'none' filter.
2458 */ 2558 */
2459 png_bytep rp; 2559 png_bytep rp;
2460 png_size_t sum = 0; 2560 png_size_t sum = 0;
2461 png_size_t i; 2561 png_size_t i;
2462 int v; 2562 int v;
2463 2563
2464 { 2564 {
2465 for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) 2565 for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
2466 { 2566 {
2467 v = *rp; 2567 v = *rp;
2468 sum += (v < 128) ? v : 256 - v; 2568 sum += (v < 128) ? v : 256 - v;
2469 } 2569 }
2470 } 2570 }
2471 2571
2472 mins = sum; 2572 mins = sum;
2473 } 2573 }
2474 2574
2475 /* Sub filter */ 2575 /* Sub filter */
2476 if (filter_to_do == PNG_FILTER_SUB) 2576 if (filter_to_do == PNG_FILTER_SUB)
2477 /* It's the only filter so no testing is needed */ 2577 /* It's the only filter so no testing is needed */
2478 { 2578 {
2479 /* Passing PNG_SIZE_MAX here and below prevents the 'setup' function 2579 png_setup_sub_row_only(png_ptr, bpp, row_bytes);
2480 * breaking out of the loop when lmins is exceeded.
2481 */
2482 (void) png_setup_sub_row(png_ptr, bpp, row_bytes, PNG_SIZE_MAX);
2483 best_row = png_ptr->try_row; 2580 best_row = png_ptr->try_row;
2484 } 2581 }
2485 2582
2486 else if ((filter_to_do & PNG_FILTER_SUB) != 0) 2583 else if ((filter_to_do & PNG_FILTER_SUB) != 0)
2487 { 2584 {
2488 png_size_t sum; 2585 png_size_t sum;
2489 png_size_t lmins = mins; 2586 png_size_t lmins = mins;
2490 2587
2491 sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins); 2588 sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);
2492 2589
2493 if (sum < mins) 2590 if (sum < mins)
2494 { 2591 {
2495 mins = sum; 2592 mins = sum;
2496 best_row = png_ptr->try_row; 2593 best_row = png_ptr->try_row;
2497 if (png_ptr->tst_row != NULL) 2594 if (png_ptr->tst_row != NULL)
2498 { 2595 {
2499 png_ptr->try_row = png_ptr->tst_row; 2596 png_ptr->try_row = png_ptr->tst_row;
2500 png_ptr->tst_row = best_row; 2597 png_ptr->tst_row = best_row;
2501 } 2598 }
2502 } 2599 }
2503 } 2600 }
2504 2601
2505 /* Up filter */ 2602 /* Up filter */
2506 if (filter_to_do == PNG_FILTER_UP) 2603 if (filter_to_do == PNG_FILTER_UP)
2507 { 2604 {
2508 (void) png_setup_up_row(png_ptr, row_bytes, PNG_SIZE_MAX); 2605 png_setup_up_row_only(png_ptr, row_bytes);
2509 best_row = png_ptr->try_row; 2606 best_row = png_ptr->try_row;
2510 } 2607 }
2511 2608
2512 else if ((filter_to_do & PNG_FILTER_UP) != 0) 2609 else if ((filter_to_do & PNG_FILTER_UP) != 0)
2513 { 2610 {
2514 png_size_t sum; 2611 png_size_t sum;
2515 png_size_t lmins = mins; 2612 png_size_t lmins = mins;
2516 2613
2517 sum = png_setup_up_row(png_ptr, row_bytes, lmins); 2614 sum = png_setup_up_row(png_ptr, row_bytes, lmins);
2518 2615
2519 if (sum < mins) 2616 if (sum < mins)
2520 { 2617 {
2521 mins = sum; 2618 mins = sum;
2522 best_row = png_ptr->try_row; 2619 best_row = png_ptr->try_row;
2523 if (png_ptr->tst_row != NULL) 2620 if (png_ptr->tst_row != NULL)
2524 { 2621 {
2525 png_ptr->try_row = png_ptr->tst_row; 2622 png_ptr->try_row = png_ptr->tst_row;
2526 png_ptr->tst_row = best_row; 2623 png_ptr->tst_row = best_row;
2527 } 2624 }
2528 } 2625 }
2529 } 2626 }
2530 2627
2531 /* Avg filter */ 2628 /* Avg filter */
2532 if (filter_to_do == PNG_FILTER_AVG) 2629 if (filter_to_do == PNG_FILTER_AVG)
2533 { 2630 {
2534 (void) png_setup_avg_row(png_ptr, bpp, row_bytes, PNG_SIZE_MAX); 2631 png_setup_avg_row_only(png_ptr, bpp, row_bytes);
2535 best_row = png_ptr->try_row; 2632 best_row = png_ptr->try_row;
2536 } 2633 }
2537 2634
2538 else if ((filter_to_do & PNG_FILTER_AVG) != 0) 2635 else if ((filter_to_do & PNG_FILTER_AVG) != 0)
2539 { 2636 {
2540 png_size_t sum; 2637 png_size_t sum;
2541 png_size_t lmins = mins; 2638 png_size_t lmins = mins;
2542 2639
2543 sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins); 2640 sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins);
2544 2641
2545 if (sum < mins) 2642 if (sum < mins)
2546 { 2643 {
2547 mins = sum; 2644 mins = sum;
2548 best_row = png_ptr->try_row; 2645 best_row = png_ptr->try_row;
2549 if (png_ptr->tst_row != NULL) 2646 if (png_ptr->tst_row != NULL)
2550 { 2647 {
2551 png_ptr->try_row = png_ptr->tst_row; 2648 png_ptr->try_row = png_ptr->tst_row;
2552 png_ptr->tst_row = best_row; 2649 png_ptr->tst_row = best_row;
2553 } 2650 }
2554 } 2651 }
2555 } 2652 }
2556 2653
2557 /* Paeth filter */ 2654 /* Paeth filter */
2558 if ((filter_to_do == PNG_FILTER_PAETH) != 0) 2655 if ((filter_to_do == PNG_FILTER_PAETH) != 0)
2559 { 2656 {
2560 (void) png_setup_paeth_row(png_ptr, bpp, row_bytes, PNG_SIZE_MAX); 2657 png_setup_paeth_row_only(png_ptr, bpp, row_bytes);
2561 best_row = png_ptr->try_row; 2658 best_row = png_ptr->try_row;
2562 } 2659 }
2563 2660
2564 else if ((filter_to_do & PNG_FILTER_PAETH) != 0) 2661 else if ((filter_to_do & PNG_FILTER_PAETH) != 0)
2565 { 2662 {
2566 png_size_t sum; 2663 png_size_t sum;
2567 png_size_t lmins = mins; 2664 png_size_t lmins = mins;
2568 2665
2569 sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins); 2666 sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins);
2570 2667
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2616 png_ptr->flush_rows++; 2713 png_ptr->flush_rows++;
2617 2714
2618 if (png_ptr->flush_dist > 0 && 2715 if (png_ptr->flush_dist > 0 &&
2619 png_ptr->flush_rows >= png_ptr->flush_dist) 2716 png_ptr->flush_rows >= png_ptr->flush_dist)
2620 { 2717 {
2621 png_write_flush(png_ptr); 2718 png_write_flush(png_ptr);
2622 } 2719 }
2623 #endif /* WRITE_FLUSH */ 2720 #endif /* WRITE_FLUSH */
2624 } 2721 }
2625 #endif /* WRITE */ 2722 #endif /* WRITE */
OLDNEW
« no previous file with comments | « third_party/libpng/README.chromium ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698