create the png data from post-deflated data
| 4694 | |
| 4695 | // create the png data from post-deflated data |
| 4696 | static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) |
| 4697 | { |
| 4698 | int bytes = (depth == 16 ? 2 : 1); |
| 4699 | stbi__context *s = a->s; |
| 4700 | stbi__uint32 i,j,stride = x*out_n*bytes; |
| 4701 | stbi__uint32 img_len, img_width_bytes; |
| 4702 | stbi_uc *filter_buf; |
| 4703 | int all_ok = 1; |
| 4704 | int k; |
| 4705 | int img_n = s->img_n; // copy it into a local for later |
| 4706 | |
| 4707 | int output_bytes = out_n*bytes; |
| 4708 | int filter_bytes = img_n*bytes; |
| 4709 | int width = x; |
| 4710 | |
| 4711 | STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); |
| 4712 | a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into |
| 4713 | if (!a->out) return stbi__err("outofmem", "Out of memory"); |
| 4714 | |
| 4715 | // note: error exits here don't need to clean up a->out individually, |
| 4716 | // stbi__do_png always does on error. |
| 4717 | if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); |
| 4718 | img_width_bytes = (((img_n * x * depth) + 7) >> 3); |
| 4719 | if (!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes)) return stbi__err("too large", "Corrupt PNG"); |
| 4720 | img_len = (img_width_bytes + 1) * y; |
| 4721 | |
| 4722 | // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, |
| 4723 | // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), |
| 4724 | // so just check for raw_len < img_len always. |
| 4725 | if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); |
| 4726 | |
| 4727 | // Allocate two scan lines worth of filter workspace buffer. |
| 4728 | filter_buf = (stbi_uc *) stbi__malloc_mad2(img_width_bytes, 2, 0); |
| 4729 | if (!filter_buf) return stbi__err("outofmem", "Out of memory"); |
| 4730 | |
| 4731 | // Filtering for low-bit-depth images |
| 4732 | if (depth < 8) { |
| 4733 | filter_bytes = 1; |
| 4734 | width = img_width_bytes; |
| 4735 | } |
| 4736 | |
| 4737 | for (j=0; j < y; ++j) { |
| 4738 | // cur/prior filter buffers alternate |
| 4739 | stbi_uc *cur = filter_buf + (j & 1)*img_width_bytes; |
| 4740 | stbi_uc *prior = filter_buf + (~j & 1)*img_width_bytes; |
| 4741 | stbi_uc *dest = a->out + stride*j; |
| 4742 | int nk = width * filter_bytes; |
| 4743 | int filter = *raw++; |
| 4744 | |
| 4745 | // check filter type |
| 4746 | if (filter > 4) { |
| 4747 | all_ok = stbi__err("invalid filter","Corrupt PNG"); |
| 4748 | break; |
| 4749 | } |
| 4750 | |
| 4751 | // if first row, use special filter that doesn't sample previous row |
| 4752 | if (j == 0) filter = first_row_filter[filter]; |
| 4753 |
no test coverage detected