CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/ext/libpng17/pngrtran.c
Views: 1401
#ifdef _MSC_VER1#pragma warning (disable:4146)2#endif34/* pngrtran.c - transforms the data in a row for PNG readers5*6* Last changed in libpng 1.7.0 [(PENDING RELEASE)]7* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson8* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)9* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)10*11* This code is released under the libpng license.12* For conditions of distribution and use, see the disclaimer13* and license in png.h14*15* This file contains functions optionally called by an application16* in order to tell libpng how to handle data when reading a PNG.17* Transformations that are used in both reading and writing are18* in pngtrans.c.19*/2021#include "pngpriv.h"22#define PNG_SRC_FILE PNG_SRC_FILE_pngrtran2324#ifdef PNG_READ_QUANTIZE_SUPPORTED25typedef struct26{27png_transform tr;28png_byte map[256U]; /* Map of palette values */29png_byte lut[1U << /* LUT for RGB values */30(PNG_QUANTIZE_RED_BITS+PNG_QUANTIZE_GREEN_BITS+PNG_QUANTIZE_BLUE_BITS)];31} png_transform_quantize;3233#define PNG_QUANTIZE_MAP 1U /* map is present and not a 1:1 mapping */34#define PNG_QUANTIZE_LUT 2U /* lut has been built */3536static void37do_quantize_rgb(png_transformp *transform, png_transform_controlp tc)38{39# define png_ptr (tc->png_ptr)40png_transform_quantize *tr = png_transform_cast(png_transform_quantize,41*transform);42unsigned int channels = PNG_TC_CHANNELS(*tc);43png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);44png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - channels/*safety*/;45png_bytep dp = png_voidcast(png_bytep, tc->dp);4647affirm(tc->bit_depth == 8 && (channels == 3 || channels == 4) &&48!(tc->format & PNG_FORMAT_FLAG_SWAPPED) &&49(tr->tr.args & PNG_QUANTIZE_LUT) != 0);5051tc->sp = dp;52tc->format |= PNG_FORMAT_FLAG_COLORMAP;5354while (sp <= ep)55{56unsigned int r = sp[0];57unsigned int g = sp[1];58unsigned int b = sp[2];5960/* This looks real messy, but the compiler will reduce61* it down to a reasonable formula. For example, with62* 5 bits per color, we get:63* p = (((r >> 3) & 0x1f) << 10) |64* (((g >> 3) & 0x1f) << 5) |65* ((b >> 3) & 0x1f);66*/67*dp++ = tr->lut[(((r >> (8 - PNG_QUANTIZE_RED_BITS)) &68((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<69(PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |70(((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &71((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<72(PNG_QUANTIZE_BLUE_BITS)) |73((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &74((1 << PNG_QUANTIZE_BLUE_BITS) - 1))];7576sp += channels;77}7879affirm(sp == ep+channels);80UNTESTED81# undef png_ptr82}8384static void85do_quantize_pal(png_transformp *transform, png_transform_controlp tc)86{87# define png_ptr (tc->png_ptr)88png_transform_quantize *tr = png_transform_cast(png_transform_quantize,89*transform);90png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);91png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc);92png_bytep dp = png_voidcast(png_bytep, tc->dp);9394affirm(tc->bit_depth == 8 && (tc->format & PNG_FORMAT_FLAG_COLORMAP) != 0 &&95!(tc->format & PNG_FORMAT_FLAG_SWAPPED) &&96(tr->tr.args & PNG_QUANTIZE_MAP) != 0);9798tc->sp = dp;99100while (sp < ep)101*dp++ = tr->map[*sp++];102103UNTESTED104# undef png_ptr105}106107static void108png_init_quantize(png_transformp *transform, png_transform_controlp tc)109{110if (tc->bit_depth == 8 && (tc->format & PNG_FORMAT_FLAG_COLOR) != 0)111{112/* Either colormapped input, RGB or RGBA: */113if (!(tc->format & PNG_FORMAT_FLAG_COLORMAP)) /* RGB, RGBA */114{115/* This must be a 'palette' lookup */116if (((*transform)->args & PNG_QUANTIZE_LUT) != 0)117{118/* This changes the format and invalidates pretty much everything in119* the info struct:120*/121tc->format |= PNG_FORMAT_FLAG_COLORMAP;122123if (tc->init == PNG_TC_INIT_FINAL)124{125(*transform)->fn = do_quantize_rgb;126tc->invalid_info |= PNG_INFO_tRNS+PNG_INFO_hIST+PNG_INFO_pCAL+127PNG_INFO_sBIT+PNG_INFO_bKGD;128tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A =129png_check_byte(tc->png_ptr, tc->bit_depth);130}131132return;133}134}135136else /* colormapped */137{138/* This must be a 'quantize' lookup */139if (((*transform)->args & PNG_QUANTIZE_MAP) != 0)140{141/* This doesn't change the format, just the values: */142if (tc->init == PNG_TC_INIT_FINAL)143{144(*transform)->fn = do_quantize_pal;145tc->invalid_info |= PNG_INFO_sBIT+PNG_INFO_pCAL;146tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A =147png_check_byte(tc->png_ptr, tc->bit_depth);148}149150return;151}152}153}154155/* Else not applicable */156(*transform)->fn = NULL;157}158159/* Dither file to 8-bit. Supply a palette, the current number160* of elements in the palette, the maximum number of elements161* allowed, and a histogram if possible. If the current number162* of colors is greater then the maximum number, the palette will be163* modified to fit in the maximum number. "full_quantize" indicates164* whether we need a quantizing cube set up for RGB images, or if we165* simply are reducing the number of colors in a paletted image.166*/167typedef struct png_dsort_struct168{169struct png_dsort_struct * next;170png_byte left;171png_byte right;172} png_dsort;173typedef png_dsort * png_dsortp;174typedef png_dsort * * png_dsortpp;175176static void177init_map(png_bytep map)178/* Initialize a mapping table to be 1:1 */179{180png_byte b = 0U;181182do183map[b] = b;184while (b++ != 255U);185}186187/* Save typing and make code easier to understand */188#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \189abs((int)((c1).green) - (int)((c2).green)) + \190abs((int)((c1).blue) - (int)((c2).blue)))191192void PNGAPI193png_set_quantize(png_structrp png_ptr, png_colorp palette,194int num_palette, int maximum_colors, png_const_uint_16p histogram,195int full_quantize)196{197png_debug(1, "in png_set_quantize");198199if (png_ptr != NULL)200{201png_transform_quantize *tr = png_transform_cast(png_transform_quantize,202png_add_transform(png_ptr, sizeof (png_transform_quantize),203png_init_quantize, PNG_TR_QUANTIZE));204205/* This is weird (consider what happens to png_set_background on a palette206* image with a tRNS chunk).207*/208if (palette == png_ptr->palette)209png_app_warning(png_ptr, "png_set_quantize: PLTE will be damaged");210211if (maximum_colors <= 0 || num_palette > 256)212{213/* The spuriously allocated transform will be removed by the init214* code.215*/216png_app_error(png_ptr, "png_set_quantize: invalid color count");217return;218}219220/* The app passed in a palette with too many colors, it's not clear why221* libpng is providing this functionality, it's nothing to do with PNG and222* can be done by the application without any PNG specific knowledge.223*/224if (num_palette > maximum_colors)225{226int map_changed = 0;227228/* The map table must be preset to do no mapping initially: */229init_map(tr->map);230231if (histogram != NULL)232{233/* This is easy enough, just throw out the least used colors.234* Perhaps not the best solution, but good enough.235*/236int i;237png_byte quantize_sort[256U];238239/* Initialize an array to sort colors */240init_map(quantize_sort);241242/* Find the least used palette entries by starting a243* bubble sort, and running it until we have sorted244* out enough colors. Note that we don't care about245* sorting all the colors, just finding which are246* least used.247*/248for (i = num_palette - 1; i >= maximum_colors; i--)249{250int done; /* To stop early if the list is pre-sorted */251int j;252253done = 1;254for (j = 0; j < i; j++)255{256if (histogram[quantize_sort[j]] <257histogram[quantize_sort[j+1]])258{259png_byte t = quantize_sort[j];260quantize_sort[j] = quantize_sort[j+1];261quantize_sort[j+1] = t;262done = 0;263}264}265266if (done != 0)267break;268}269270/* Swap the palette around, and set up a table, if necessary */271if (full_quantize)272{273int j = num_palette;274275/* Put all the useful colors within the max, but don't276* move the others.277*278* NOTE: if the app passes in the result of png_get_PLTE it will279* be overwritten at this point, what is the API?280*/281for (i = 0; i < maximum_colors; i++)282{283if (quantize_sort[i] >= maximum_colors)284{285do286j--;287while (quantize_sort[j] >= maximum_colors);288289/* NOTE: NOT swapped, so the original palette[i] has been290* lost.291*/292palette[i] = palette[j];293}294}295}296297else /* !full_quantize */298{299int j = num_palette;300301/* Move all the used colors inside the max limit, and302* develop a translation table.303*/304for (i = 0; i < maximum_colors; i++)305{306/* Only move the colors we need to */307if (quantize_sort[i] >= maximum_colors)308{309png_color tmp_color;310311do312j--;313while (quantize_sort[j] >= maximum_colors);314315tmp_color = palette[j];316palette[j] = palette[i];317palette[i] = tmp_color;318/* Indicate where the color went */319tr->map[j] = png_check_byte(png_ptr, i);320tr->map[i] = png_check_byte(png_ptr, j);321map_changed = 1;322}323}324325/* Find closest color for those colors we are not using */326for (i = 0; i < num_palette; i++)327{328if (tr->map[i] >= maximum_colors)329{330int min_d, k, min_k, d_index;331332/* Find the closest color to one we threw out */333d_index = tr->map[i];334min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);335for (k = 1, min_k = 0; k < maximum_colors; k++)336{337int d;338339d = PNG_COLOR_DIST(palette[d_index], palette[k]);340341if (d < min_d)342{343min_d = d;344min_k = k;345}346}347348/* Point to closest color */349tr->map[i] = png_check_byte(png_ptr, min_k);350map_changed = 1;351}352}353} /* !full_quantize */354} /* have a histogram */355356else /* no histogram */357{358/* This is much harder to do simply (and quickly). Perhaps359* we need to go through a median cut routine, but those360* don't always behave themselves with only a few colors361* as input. So we will just find the closest two colors,362* and throw out one of them (chosen somewhat randomly).363* [We don't understand this at all, so if someone wants to364* work on improving it, be our guest - AED, GRP]365*/366int max_d;367int num_new_palette;368png_byte index_to_palette[256U];369png_byte palette_to_index[256U];370png_dsortp hash[769];371372/* Initialize palette index sort arrays */373init_map(index_to_palette);374init_map(palette_to_index);375memset(hash, 0, sizeof hash);376num_new_palette = num_palette;377378/* Initial wild guess at how far apart the farthest pixel379* pair we will be eliminating will be. Larger380* numbers mean more areas will be allocated, Smaller381* numbers run the risk of not saving enough data, and382* having to do this all over again.383*384* I have not done extensive checking on this number.385*/386max_d = 96;387388while (num_new_palette > maximum_colors)389{390int i;391png_dsortp t = NULL;392393for (i = 0; i < num_new_palette - 1; i++)394{395int j;396397for (j = i + 1; j < num_new_palette; j++)398{399int d = PNG_COLOR_DIST(palette[i], palette[j]);400401if (d <= max_d)402{403404t = png_voidcast(png_dsortp, png_malloc_warn(png_ptr,405sizeof (*t)));406407if (t == NULL)408break;409410t->next = hash[d];411t->left = png_check_byte(png_ptr, i);412t->right = png_check_byte(png_ptr, j);413hash[d] = t;414}415}416if (t == NULL)417break;418}419420if (t != NULL) for (i = 0; i <= max_d; i++)421{422if (hash[i] != NULL)423{424png_dsortp p;425426for (p = hash[i]; p != NULL; p = p->next)427{428if (index_to_palette[p->left] < num_new_palette &&429index_to_palette[p->right] < num_new_palette)430{431int j, next_j;432433if (num_new_palette & 0x01)434{435j = p->left;436next_j = p->right;437}438else439{440j = p->right;441next_j = p->left;442}443444num_new_palette--;445/* NOTE: overwrites palette */446palette[index_to_palette[j]] =447palette[num_new_palette];448449if (full_quantize == 0)450{451int k;452453for (k = 0; k < num_palette; k++)454{455if (tr->map[k] == index_to_palette[j])456{457tr->map[k] = index_to_palette[next_j];458map_changed = 1;459}460461if (tr->map[k] == num_new_palette)462{463tr->map[k] = index_to_palette[j];464map_changed = 1;465}466}467}468469index_to_palette[palette_to_index[num_new_palette]] =470index_to_palette[j];471472palette_to_index[index_to_palette[j]] =473palette_to_index[num_new_palette];474475index_to_palette[j] =476png_check_byte(png_ptr, num_new_palette);477478palette_to_index[num_new_palette] =479png_check_byte(png_ptr, j);480}481482if (num_new_palette <= maximum_colors)483break;484}485486if (num_new_palette <= maximum_colors)487break;488}489}490491for (i = 0; i < 769; i++)492{493if (hash[i] != NULL)494{495png_dsortp p = hash[i];496497while (p)498{499t = p->next;500png_free(png_ptr, p);501p = t;502}503504hash[i] = NULL;505}506}507508max_d += 96;509} /* while num_new_colors > maximum_colors */510} /* no histogram */511512num_palette = maximum_colors;513514if (map_changed) /* else the map is 1:1 */515tr->tr.args |= PNG_QUANTIZE_MAP;516} /* num_palette > maximum_colors */517518/* The palette has been reduced to the requested number of colors if it519* was over maximum colors before.520*/521522/* TODO: what is this? Apparently the png_struct::palette member gets523* updated if it didn't originally have a palette, but the update relies524* on the app not freeing the passed in palette.525*/526if (png_ptr->palette == NULL)527png_ptr->palette = palette;528529png_ptr->num_palette = png_check_bits(png_ptr, num_palette, 9);530531if (full_quantize)532{533int i;534png_byte distance[1U << (PNG_QUANTIZE_RED_BITS+PNG_QUANTIZE_GREEN_BITS+535PNG_QUANTIZE_BLUE_BITS)];536537memset(distance, 0xff, sizeof distance);538539for (i = 0; i < num_palette; i++)540{541int ir;542int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));543int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));544int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));545546for (ir = 0; ir < (1<<PNG_QUANTIZE_RED_BITS); ir++)547{548/* int dr = abs(ir - r); */549int ig;550int dr = ((ir > r) ? ir - r : r - ir);551int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +552PNG_QUANTIZE_GREEN_BITS));553554for (ig = 0; ig < (1<<PNG_QUANTIZE_GREEN_BITS); ig++)555{556/* int dg = abs(ig - g); */557int ib;558int dg = ((ig > g) ? ig - g : g - ig);559int dt = dr + dg;560int dm = ((dr > dg) ? dr : dg);561int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);562563for (ib = 0; ib < (1<<PNG_QUANTIZE_BLUE_BITS); ib++)564{565int d_index = index_g | ib;566/* int db = abs(ib - b); */567int db = ((ib > b) ? ib - b : b - ib);568int dmax = ((dm > db) ? dm : db);569int d = dmax + dt + db;570571if (d < distance[d_index])572{573distance[d_index] = png_check_byte(png_ptr, d);574tr->lut[d_index] = png_check_byte(png_ptr, i);575}576} /* for blue */577} /* for green */578} /* for red */579} /* num_palette */580} /* full_quantize */581} /* png_ptr != NULL */582}583#endif /* READ_QUANTIZE */584585#ifdef PNG_READ_PACK_SUPPORTED586/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,587* without changing the actual values. Thus, if you had a row with588* a bit depth of 1, you would end up with bytes that only contained589* the numbers 0 or 1. If you would rather they contain 0 and 255, use590* png_set_expand_gray_1_2_4_to_8 instead.591*/592static void593png_do_read_unpack(png_transformp *transform, png_transform_controlp tc)594{595png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);596png_const_bytep ep = png_voidcast(png_const_bytep, tc->dp);597png_bytep dp = png_voidcast(png_bytep, tc->dp);598599sp += PNG_TC_ROWBYTES(*tc) - 1; /* Start from end */600dp += tc->width; /* output bit depth is 8 */601602# define png_ptr (tc->png_ptr)603png_debug(1, "in png_do_unpack");604605switch (tc->bit_depth)606{607case 1:608{609/* Because we copy from the last pixel down the shift required610* at the start is 8-pixels_in_last_byte, which is just:611*/612unsigned int shift = 7U & -tc->width;613614while (dp > ep)615{616*--dp = (*sp >> shift) & 1U;617shift = 7U & (shift+1U);618if (shift == 0U)619--sp;620}621622debug(shift == 0U);623break;624}625626case 2:627{628unsigned int shift = 7U & -(tc->width << 1);629630while (dp > ep)631{632*--dp = (*sp >> shift) & 3U;633shift = 7U & (shift+2U);634if (shift == 0U)635--sp;636}637638debug(shift == 0U);639break;640}641642case 4:643{644unsigned int shift = 7U & -(tc->width << 2);645646while (dp > ep)647{648*--dp = (*sp >> shift) & 15U;649shift = 7U & (shift+4U);650if (shift == 0U)651--sp;652}653654debug(shift == 0U);655break;656}657658default:659impossible("bit depth");660}661662debug(dp == ep && sp == png_upcast(png_const_bytep, tc->sp)-1U);663tc->sp = dp;664665if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0U)666{667tc->range++;668tc->format |= PNG_FORMAT_FLAG_RANGE;669}670671tc->bit_depth = 8U;672PNG_UNUSED(transform)673# undef png_ptr674}675676/* Called from the curiously named png_set_packing API in pngtrans.c; the read677* and write code is separated because read 'unpacks' (from PNG format) and678* write 'packs' (to PNG format.)679*/680void /* PRIVATE */681png_init_read_pack(png_transformp *transform, png_transform_controlp tc)682{683# define png_ptr tc->png_ptr684debug(tc->init);685686if (tc->bit_depth < 8) /* else no packing/unpacking */687{688/* For indexed images the pack operation does not invalidate the range; in689* fact the corresponding shift operation would!690*/691if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0U)692{693tc->range++;694tc->format |= PNG_FORMAT_FLAG_RANGE;695}696697tc->bit_depth = 8U;698699if (tc->init == PNG_TC_INIT_FINAL)700(*transform)->fn = png_do_read_unpack/* sic: it unpacks */;701}702703else /* the transform is not applicable */704(*transform)->fn = NULL;705706# undef png_ptr707}708#endif /* READ_PACK */709710#if defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)711# ifdef PNG_READ_tRNS_SUPPORTED712static unsigned int713fill_transparent_pixel(png_const_structrp png_ptr, png_byte *trans)714/* Fill a byte array according to the transparent pixel value and return a715* count of the number of bytes. Low bit depth gray values are replicated in716* the first byte. Writes from 1 to 6 bytes.717*/718{719/* There must be a tRNS chunk and this must not be a palette image: */720debug(png_ptr->num_trans == 1 &&721!(png_ptr->color_type & (PNG_COLOR_MASK_ALPHA+PNG_COLOR_MASK_PALETTE)));722723if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* gray */724{725unsigned int t = png_ptr->trans_color.gray;726unsigned int depth = png_ptr->bit_depth;727728if (depth < 16U)729{730/* ISO PNG 11.3.2.1 "tRNS Transparency": "If the image bit depth is731* less than 16, the least significant bits are used and the others are732* 0." So mask out the upper bits.733*/734t &= (1U<<depth)-1U;735736/* And replicate low bit-depth values across the byte: */737while (depth < 8U)738{739t |= t << depth;740depth <<= 1;741}742743trans[0] = PNG_BYTE(t);744return 1U;745}746747/* Else a 16 bit value: */748trans[0] = PNG_BYTE(t >> 8);749trans[1] = PNG_BYTE(t);750return 2U;751}752753else /* color */ switch (png_ptr->bit_depth)754{755case 8: /* 8-bit RGB */756trans[0] = PNG_BYTE(png_ptr->trans_color.red);757trans[1] = PNG_BYTE(png_ptr->trans_color.green);758trans[2] = PNG_BYTE(png_ptr->trans_color.blue);759return 3U;760761case 16: /* 16-bit RGB */762trans[0] = PNG_BYTE(png_ptr->trans_color.red >> 8);763trans[1] = PNG_BYTE(png_ptr->trans_color.red);764trans[2] = PNG_BYTE(png_ptr->trans_color.green >> 8);765trans[3] = PNG_BYTE(png_ptr->trans_color.green);766trans[4] = PNG_BYTE(png_ptr->trans_color.blue >> 8);767trans[5] = PNG_BYTE(png_ptr->trans_color.blue);768return 6U;769770default:771NOT_REACHED;772return 0U; /* safe */773}774}775# endif /* READ_tRNS */776#endif /* READ_EXPAND || READ_BACKGROUND */777778#ifdef PNG_READ_EXPAND_SUPPORTED779/* Flags for png_init_expand */780#define PNG_EXPAND_PALETTE 1U /* palette images only, includes tRNS */781#define PNG_EXPAND_LBD_GRAY 2U /* grayscale low-bit depth only */782#define PNG_EXPAND_tRNS 4U /* non-palette images only */783784/* This struct is only required for tRNS matching, but it is convenient to785* allocated it anyway even if READ_tRNS is not supported.786*/787typedef struct788{789png_transform tr;790unsigned int ntrans; /* number of bytes below */791png_byte transparent_pixel[6]; /* the transparent pixel value */792} png_expand;793794#ifdef PNG_READ_tRNS_SUPPORTED795/* Look for colors matching the trans_color in png_ptr, low bit depth gray is796* covered below so this only need handle 8 abd 16-bit channels.797*/798static void799png_do_expand_tRNS(png_transformp *transform, png_transform_controlp tc)800{801# define png_ptr (tc->png_ptr)802png_expand *tr = png_transform_cast(png_expand, *transform);803png_bytep dp = png_voidcast(png_bytep, tc->dp);804png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);805const png_const_bytep ep = sp;806const unsigned int spixel_size = PNG_TC_PIXEL_DEPTH(*tc) >> 3;807unsigned int alpha_size;808809/* We expect opaque and transparent pixels to be interleaved but with long810* sequences of each. Because we are adding an alpha channel we must copy811* down.812*/813debug(!(tc->format & PNG_FORMAT_FLAG_ALPHA));814debug(spixel_size == tr->ntrans);815sp += PNG_TC_ROWBYTES(*tc);816tc->sp = dp;817tc->format |= PNG_FORMAT_FLAG_ALPHA;818tc->invalid_info |= PNG_INFO_tRNS;819tc->transparent_alpha = 1U;820alpha_size = (PNG_TC_PIXEL_DEPTH(*tc)>>3) - spixel_size;821debug(alpha_size == 1 || alpha_size == 2);822dp += PNG_TC_ROWBYTES(*tc);823824do825{826unsigned int i = spixel_size;827png_byte alpha = 0U;828829dp -= alpha_size;830alpha = 0U;831832/* Copy and check one source pixel (backwards, to avoid any833* overwrite):834*/835do if ((*--dp = *--sp) != tr->transparent_pixel[--i]) /* pixel != tRNS */836alpha = 0xFFU;837while (i != 0U);838839/* i == 0 */840do841dp[spixel_size + i] = alpha;842while (++i < alpha_size);843} while (sp > ep);844845debug(sp == ep && dp == tc->dp); /* else overwrite */846# undef png_ptr847}848#endif /* READ_tRNS */849850/* Expand grayscale images of less than 8-bit depth to 8 bits.851* libpng 1.7.0: this no longer expands everything, it just expands the low bit852* depth gray row. It does *NOT* expand the tRNS into an alpha channel unless853* it is told to do so.854*855* API CHANGE: the function now does what it was always meant to do.856*857* This is like do_unpack except that the packed data is expanded to the full858* 8-bit range; scaled up. This is not a good thing to do on an indexed image;859* the indices will be invalid.860*861* The tRNS handling is included here too; speed is not important because the862* result will always be cached unless the PNG is very small.863*/864static void865png_do_expand_lbd_gray(png_transformp *transform, png_transform_controlp tc)866{867# define png_ptr (tc->png_ptr)868png_bytep dp = png_voidcast(png_bytep, tc->dp);869const png_const_bytep ep = dp;870png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);871const unsigned int bit_depth = tc->bit_depth;872# ifdef PNG_READ_sBIT_SUPPORTED873unsigned int insignificant_bits = 0U;874# endif /* READ_sBIT */875# ifdef PNG_READ_tRNS_SUPPORTED876unsigned int gray = 0xffffU; /* doesn't match anything */877unsigned int do_alpha = 0U;878# endif /* READ_tRNS */879880sp += PNG_TC_ROWBYTES(*tc); /* last byte +1 */881tc->bit_depth = 8U;882tc->invalid_info |= PNG_INFO_tRNS;883# ifdef PNG_READ_sBIT_SUPPORTED884if (bit_depth > 1U /* irrelevant for bit depth 1 */ &&885!(tc->invalid_info & PNG_INFO_sBIT) &&886tc->sBIT_G > 0U/*SAFETY*/ && tc->sBIT_G < bit_depth)887insignificant_bits = bit_depth - tc->sBIT_G;888# endif /* READ_sBIT */889890# ifdef PNG_READ_tRNS_SUPPORTED891if (((*transform)->args & PNG_EXPAND_tRNS) != 0)892{893tc->format |= PNG_FORMAT_FLAG_ALPHA;894tc->transparent_alpha = 1U;895gray = png_ptr->trans_color.gray & ((1U << bit_depth)-1U);896do_alpha = 1U;897}898899/* This helps avoid cluttering the code up with #ifdefs: */900# define check_tRNS if (do_alpha) *--dp = (pixel != gray) * 255U;901# else /* !READ_tRNS */902# define check_tRNS903# endif /* READ_tRNS */904905dp += PNG_TC_ROWBYTES(*tc); /* pre-decremented below */906907switch (bit_depth)908{909case 1:910{911unsigned int shift = 7U & -tc->width;912unsigned int s = *--sp;913914for(;;)915{916if (shift == 8U) s = *--sp, shift = 0;917918{919const unsigned int pixel = (s >> shift) & 1U;920921check_tRNS922*--dp = PNG_BYTE(pixel * 255U);923if (dp <= ep) break;924}925++shift;926}927928debug(dp == ep && shift == 7U && sp == tc->sp);929break;930}931932case 2:933{934unsigned int shift = 7U & -(tc->width << 1)/*overflow ok*/;935unsigned int s = *--sp;936937for (;;)938{939if (shift == 8U) s = *--sp, shift = 0;940{941const unsigned int pixel = (s >> shift) & 3U;942943check_tRNS944945# ifdef PNG_READ_sBIT_SUPPORTED946/* 'sig_bits' must be 1 or 2 leaving insignificant_bits 0 or947* 1. This may look silly but it allows a compact representation948* of 1 bit gray + 1 bit alpha (transparency):949*/950if (insignificant_bits /* only 1 bit significant */)951*--dp = PNG_BYTE((pixel >> 1) * 255U);952953else954# endif955*--dp = PNG_BYTE(pixel * 85U);956957if (dp <= ep) break;958}959shift += 2U;960}961962debug(dp == ep && shift == 6U && sp == tc->sp);963break;964}965966case 4:967{968unsigned int shift = 7U & -(tc->width << 2)/*overflow ok*/;969unsigned int s = *--sp;970# ifdef PNG_READ_sBIT_SUPPORTED971const unsigned int div = (1U << (4U-insignificant_bits)) - 1U;972# endif973974for (;;)975{976if (shift == 8U) s = *--sp, shift = 0;977{978unsigned int pixel = (s >> shift) & 15U;979980check_tRNS981982# ifdef PNG_READ_sBIT_SUPPORTED983/* insignificant_bits may be 0, 1, 2 or 3, requiring a multiply984* by 17, 255/7, 85 or 255. Since this operation is always985* cached we don't much care about the time to do the divide986* below.987*/988if (insignificant_bits)989pixel = ((pixel>>insignificant_bits) * 255U + (div>>1)) / div;990991else992# endif993pixel *= 17U;994995*--dp = PNG_BYTE(pixel);996if (dp <= ep) break;997}998999shift += 4U;1000}10011002debug(dp == ep && shift == 4U && sp == tc->sp);1003break;1004}10051006default:1007impossible("bit depth");1008}10091010tc->sp = ep;10111012# undef check_tRNS1013# undef png_ptr1014}10151016static void1017png_init_expand(png_transformp *transform, png_transform_controlp tc)1018{1019# define png_ptr (tc->png_ptr)1020/* The possible combinations are:1021*1022* 1) PALETTE: the 'palette' flag should be set on the transform control and1023* all that need be done is cancel this to cause the cache code to do the1024* expansion.1025*1026* 2) LBP_GRAY, LBP_GRAY+tRNS: use png_do_expand_lbd_gray to do the required1027* expand. Can be cached.1028*1029* 3) tRNS: scan the row for the relevant tRNS value.1030*1031* Note that expanding 8 to 16 bits is a byte op in pngtrans.c (it just1032* replicates bytes).1033*/1034if (tc->palette)1035{1036debug(tc->caching && !(tc->format & PNG_FORMAT_FLAG_COLORMAP));10371038if (((*transform)->args & PNG_EXPAND_PALETTE) != 0U)1039{1040tc->palette = 0U;1041tc->invalid_info |= PNG_INFO_PLTE + PNG_INFO_tRNS;1042tc->cost = PNG_CACHE_COST_LIMIT; /* the cache is required! */1043}10441045/* Note that this needs to happen when the row is processed (!tc->init) as1046* well.1047*/1048}10491050else if (!(tc->format & PNG_FORMAT_FLAG_COLORMAP))1051{1052png_uint_32 args = (*transform)->args & PNG_BIC_MASK(PNG_EXPAND_PALETTE);1053unsigned int bit_depth = tc->bit_depth;10541055debug(tc->init);10561057if (bit_depth >= 8U)1058args &= PNG_BIC_MASK(PNG_EXPAND_LBD_GRAY);10591060# ifdef PNG_READ_tRNS_SUPPORTED1061if (png_ptr->num_trans == 0U ||1062(tc->format & PNG_FORMAT_FLAG_ALPHA) != 0U ||1063(tc->invalid_info & PNG_INFO_tRNS) != 0U)1064# endif1065args &= PNG_BIC_MASK(PNG_EXPAND_tRNS);10661067(*transform)->args = args;10681069switch (args)1070{1071case PNG_EXPAND_LBD_GRAY:1072tc->bit_depth = 8U;1073tc->invalid_info |= PNG_INFO_tRNS;10741075if (tc->init == PNG_TC_INIT_FINAL)1076(*transform)->fn = png_do_expand_lbd_gray;1077break;10781079# ifdef PNG_READ_tRNS_SUPPORTED1080case PNG_EXPAND_LBD_GRAY + PNG_EXPAND_tRNS:1081tc->bit_depth = 8U;1082tc->format |= PNG_FORMAT_FLAG_ALPHA;1083tc->invalid_info |= PNG_INFO_tRNS;1084tc->transparent_alpha = 1U;10851086/* In this case tRNS must be left unmodified for the expansion code1087* to handle.1088*/1089if (tc->init == PNG_TC_INIT_FINAL)1090(*transform)->fn = png_do_expand_lbd_gray;1091break;10921093case PNG_EXPAND_tRNS:1094if (tc->init == PNG_TC_INIT_FINAL)1095{1096png_expand *tr = png_transform_cast(png_expand, *transform);10971098affirm((tc->bit_depth == 8U || tc->bit_depth == 16U) &&1099(tc->format &1100(PNG_FORMAT_FLAG_COLORMAP|PNG_FORMAT_FLAG_ALPHA)) == 0U);11011102tr->ntrans = fill_transparent_pixel(png_ptr,1103tr->transparent_pixel);1104tr->tr.fn = png_do_expand_tRNS;1105} /* TC_INIT_FINAL */11061107tc->format |= PNG_FORMAT_FLAG_ALPHA;1108tc->invalid_info |= PNG_INFO_tRNS;1109tc->transparent_alpha = 1U;1110break;1111# endif /* READ_tRNS */11121113default: /* transform not applicable */1114(*transform)->fn = NULL;1115break;1116}11171118implies(tc->init == PNG_TC_INIT_FINAL,1119(*transform)->fn != png_init_expand);1120}11211122else /* not applicable */1123{1124debug(tc->init);1125(*transform)->fn = NULL;1126NOT_REACHED;1127}1128# undef png_ptr1129}11301131void PNGAPI1132png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)1133{1134if (png_ptr != NULL)1135png_add_transform(png_ptr, sizeof (png_expand), png_init_expand,1136PNG_TR_EXPAND)->args |= PNG_EXPAND_LBD_GRAY;1137}11381139/* Expand paletted images to 8-bit RGB or, if there is a tRNS chunk, RGBA.1140* Note that this is effectively handled by the read code palette optimizations.1141*1142* API CHANGE: this used to have the completely unexpected side effect of1143* turning on the above two optimizations.1144*/1145void PNGAPI1146png_set_palette_to_rgb(png_structrp png_ptr)1147{1148if (png_ptr != NULL)1149png_add_transform(png_ptr, sizeof (png_expand), png_init_expand,1150PNG_TR_EXPAND)->args |= PNG_EXPAND_PALETTE;1151}11521153/* Expand paletted images to RGB, expand grayscale images of less than 8-bit1154* depth to 8-bit depth, and expand tRNS chunks to alpha channels. I.e. all the1155* above.1156*/1157void PNGAPI1158png_set_expand(png_structrp png_ptr)1159{1160if (png_ptr != NULL)1161{1162png_set_palette_to_rgb(png_ptr);1163png_set_expand_gray_1_2_4_to_8(png_ptr);1164png_set_tRNS_to_alpha(png_ptr);1165}1166}1167#endif /* READ_EXPAND */11681169#if defined(PNG_READ_EXPAND_SUPPORTED) ||\1170defined(PNG_READ_STRIP_ALPHA_SUPPORTED)11711172#define PNG_INIT_STRIP_ALPHA 1U1173#define PNG_INIT_EXPAND_tRNS 2U1174static void1175png_init_alpha(png_transformp *transform, png_transform_controlp tc)1176{1177# define png_ptr (tc->png_ptr)1178int required = 0;11791180# if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_tRNS_SUPPORTED)1181if ((*transform)->args & PNG_INIT_EXPAND_tRNS)1182{1183/* Prior to 1.7 the alpha channel was stripped after expanding the tRNS1184* chunk, so this effectively cancelled out the expand.1185*/1186if (png_ptr->num_trans > 0 && !tc->palette &&1187!((*transform)->args & PNG_INIT_STRIP_ALPHA))1188{1189debug((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0);11901191required = 1;1192tc->expand_tRNS = 1U;11931194/* This happens as a result of an explicit API call to1195* png_set_tRNS_to_alpha, so expand low-bit-depth gray too:1196*/1197if (tc->init == PNG_TC_INIT_FORMAT)1198png_add_transform(png_ptr, sizeof (png_expand), png_init_expand,1199PNG_TR_EXPAND)->args |= PNG_EXPAND_tRNS + PNG_EXPAND_LBD_GRAY;1200}12011202else1203(*transform)->args &= PNG_BIC_MASK(PNG_INIT_EXPAND_tRNS);1204}1205# endif /* READ_EXPAND && READ_tRNS */12061207# ifdef PNG_READ_STRIP_ALPHA_SUPPORTED1208if ((*transform)->args & PNG_INIT_STRIP_ALPHA)1209{1210/* When compose is being done tRNS will be expanded regardless of the1211* above test. Rather that trying to work out if this will happen the1212* code just inserts a strip operation; it will be removed later if it1213* is not needed.1214*/1215required = 1;1216tc->strip_alpha = 1U;12171218if (tc->init == PNG_TC_INIT_FORMAT)1219png_add_strip_alpha_byte_ops(png_ptr);1220}1221# endif /* READ_STRIP_ALPHA */12221223if (!required)1224(*transform)->fn = NULL;1225# undef png_ptr1226}1227#endif /* READ_EXPAND || READ_STRIP_ALPHA */12281229#ifdef PNG_READ_EXPAND_SUPPORTED1230/* Expand tRNS chunks to alpha channels. This only expands the tRNS chunk on1231* non-palette formats; call png_set_palette_to_rgb to get the corresponding1232* effect for a palette.1233*1234* Note that this will expand low bit depth gray if there is a tRNS chunk, but1235* if not nothing will happen.1236*1237* API CHANGE: this used to do all the expansions, it was rather pointless1238* calling it.1239*/1240void PNGAPI1241png_set_tRNS_to_alpha(png_structrp png_ptr)1242{1243if (png_ptr != NULL)1244png_add_transform(png_ptr, 0/*size*/, png_init_alpha, PNG_TR_INIT_ALPHA)->1245args |= PNG_INIT_EXPAND_tRNS;1246}1247#endif /* READ_EXPAND */12481249#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED1250void PNGAPI1251png_set_strip_alpha(png_structrp png_ptr)1252{1253if (png_ptr != NULL)1254png_add_transform(png_ptr, 0/*size*/, png_init_alpha, PNG_TR_INIT_ALPHA)->1255args |= PNG_INIT_STRIP_ALPHA;1256}1257#endif /* READ_STRIP_ALPHA */12581259#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED1260static void1261png_do_chop_16_to_8(png_transformp *transform, png_transform_controlp tc)1262/* This is actually a repeat of the byte transform, unnecessary code1263* replication.1264*1265* TODO: remove this1266*/1267{1268# define png_ptr (tc->png_ptr)1269png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); /* source */1270png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc); /* end+1 */1271png_bytep dp = png_voidcast(png_bytep, tc->dp); /* destination */12721273debug(tc->bit_depth == 16U);1274tc->sp = dp;1275tc->bit_depth = 8U;12761277while (sp < ep)1278*dp++ = *sp, sp += 2;12791280debug(sp == ep);1281# undef png_ptr12821283PNG_UNUSED(transform)1284}12851286/* A transform containing some useful scaling values... */1287typedef struct1288{1289png_transform tr;1290png_uint_32 shifts; /* 4 4-bit values preceeded by a shibboleth (1) */1291png_uint_32 channel_scale[4];1292} png_transform_scale_16_to_8;12931294/* Scale rows of bit depth 16 down to 8 accurately */1295static void1296png_do_scale_16_to_8(png_transformp *transform, png_transform_controlp tc)1297{1298# define png_ptr (tc->png_ptr)1299png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); /* source */1300png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc); /* end+1 */1301png_bytep dp = png_voidcast(png_bytep, tc->dp); /* destination */1302png_transform_scale_16_to_8 *tr =1303png_transform_cast(png_transform_scale_16_to_8, *transform);1304png_uint_32p scale = 0;1305png_uint_32 shift = 1U; /* set the shibboleth at the start */13061307debug(tc->bit_depth == 16U);1308tc->sp = dp;1309tc->bit_depth = 8U;13101311while (sp < ep)1312{1313/* The input is an array of 16 bit components, these must be scaled to1314* 8 bits each taking into account the sBIT setting. The calculation1315* requires that the insignificant bits be stripped from the input value1316* via a shift then scaled back to 8 bits:1317*1318* output = ((input >> shift) * scale + round) >> 241319*1320* The shifts are packed into tr->shifts, with the end of the list marked1321* by a shibboleth, 1, which is preset above.1322*/1323png_uint_32 v = png_get_uint_16(sp);13241325sp += 2;13261327if (shift == 1U)1328{1329shift = tr->shifts;1330scale = tr->channel_scale;1331}13321333*dp++ = PNG_BYTE(((v >> (shift & 0xFU)) * *scale++ + 0x800000U) >> 24);1334shift >>= 4;1335}13361337affirm(sp == ep);1338# undef png_ptr1339}13401341static int1342add_scale(png_transform_scale_16_to_8 *tr, unsigned int sBIT, unsigned int ch)1343{1344/* This is the output max (255) scaled by 2^24 divided by the input max'1345* (which is variable) and rounded. It gives the exact 8-bit answer for all1346* input sBIT depths when used in the calculation:1347*1348* output = ((input >> shift) * scale + 0x800000U) >> 241349*/1350tr->channel_scale[ch] = (0xFF000000U + ((1U<<sBIT)>>1)) / ((1U<<sBIT)-1U);1351tr->shifts |= ((16U-sBIT) & 0xFU) << (4U*ch);13521353/* The result says whether there are 8 or fewer significant bits in the1354* input value; if so we can just drop the low byte.1355*/1356return sBIT <= 8U;1357}13581359static void1360png_init_scale_16_to_8(png_transformp *transform, png_transform_controlp tc)1361{1362if (tc->bit_depth == 16U)1363{1364# define png_ptr (tc->png_ptr)1365tc->bit_depth = 8U;1366/* But this invalidates tRNS (a 16-bit tRNS cannot be updated to match1367* 8-bit data correctly).1368*/1369tc->invalid_info |= PNG_INFO_tRNS+PNG_INFO_hIST+PNG_INFO_pCAL;1370/* TODO: These need further processing: PNG_INFO_bKGD */13711372if (tc->init == PNG_TC_INIT_FINAL)1373{1374png_transform_scale_16_to_8 *tr =1375png_transform_cast(png_transform_scale_16_to_8, *transform);13761377/* Set the scale factors for each channel (up to 4), the factors are1378* made so that:1379*1380* ((channel >> shift) * factor + 0x800000U) >> 241381*1382* Gives the required 8-bit value. The 'shift' is stored in a single1383* png_uint_32 with a shibboleth at the end.1384*/1385unsigned int channels = 0U;1386int chop_ok = 1;13871388tr->shifts = 0U;13891390/* This adds up to four scale factors, the remainder are left as 01391* which is safe and leads to obvious errors in the output images in1392* the event of an (internal) error.1393*/1394if (tc->format & PNG_FORMAT_FLAG_COLOR)1395chop_ok &= add_scale(tr, tc->sBIT_R, channels++);13961397chop_ok &= add_scale(tr, tc->sBIT_G, channels++);13981399if (tc->format & PNG_FORMAT_FLAG_COLOR)1400chop_ok &= add_scale(tr, tc->sBIT_B, channels++);14011402if (tc->format & PNG_FORMAT_FLAG_ALPHA)1403chop_ok &= add_scale(tr, tc->sBIT_A, channels++);14041405if (chop_ok)1406tr->tr.fn = png_do_chop_16_to_8;14071408else1409{1410int handled = 1;14111412/* Add the shibboleth at the end */1413tr->shifts |= 1U << (4U*channels);1414tr->tr.fn = png_do_scale_16_to_8;14151416/* sBIT is a little tricky; it has to be processed in the scaling1417* operation. The result will have the same number of bits unless1418* there were more than 8 before. The sBIT flags in the transform1419* control are left unchanged here because the data is still valid,1420* unless all the values end up as 8 in which case there is no1421* remaining sBIT info.1422*1423* Note that fields, such as alpha, which are not set for this row1424* format will always have max values, so won't reset 'handled':1425*/1426if (tc->sBIT_R >= 8U) tc->sBIT_R = 8U; else handled = 0;1427if (tc->sBIT_G >= 8U) tc->sBIT_G = 8U; else handled = 0;1428if (tc->sBIT_B >= 8U) tc->sBIT_B = 8U; else handled = 0;1429if (tc->sBIT_A >= 8U) tc->sBIT_A = 8U; else handled = 0;14301431/* If all the sBIT values were >= 8U all the bits are now1432* significant:1433*/1434if (handled)1435tc->invalid_info |= PNG_INFO_sBIT;1436}1437}14381439# undef png_ptr1440}14411442else /* not applicable */1443(*transform)->fn = NULL;1444}14451446void PNGAPI1447png_set_scale_16(png_structrp png_ptr)1448{1449if (png_ptr != NULL)1450png_add_transform(png_ptr, sizeof (png_transform_scale_16_to_8),1451png_init_scale_16_to_8, PNG_TR_SCALE_16_TO_8);1452}1453#endif /* READ_SCALE_16_TO_8 */14541455#ifdef PNG_READ_GAMMA_SUPPORTED1456/* Code that depends on READ_GAMMA support; RGB to gray convertion and1457* background composition (including the various alpha-mode handling1458* operations which produce pre-multiplied alpha by composing on 0).1459*/1460/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */1461static png_fixed_point1462png_reciprocal(png_fixed_point a)1463{1464#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED1465double r = floor(1E10/a+.5);14661467if (r <= 2147483647. && r >= -2147483648.)1468return (png_fixed_point)r;1469#else1470png_fixed_point res;14711472if (png_muldiv(&res, PNG_FP_1, PNG_FP_1, a) != 0)1473return res;1474#endif14751476return 0; /* error/overflow */1477}14781479/* This is the shared test on whether a gamma value is 'significant' - whether1480* it is worth doing gamma correction. 'significant_bits' is the number of bits1481* in the values to be corrected which are significant.1482*/1483static int1484png_gamma_significant(png_const_structrp png_ptr, png_fixed_point gamma_val,1485unsigned int sbits)1486{1487#if 01488/* This seems to be wrong. The issue is that when the app asks for a higher1489* bit depth output than the input has significant bits it causes gamma1490* correction to be skipped (this was the intent) however there's no1491* particular guarantee that the app won't go on to do further gamma1492* processing - pngstest does this - and this messes up the results1493* completely.1494*1495* TODO: work out how to optimize this correctly.1496*/1497/* The following table lists the threshold as a difference from PNG_FP_1 at1498* which the gamma correction will make a change to at least an 'sbits'1499* value. There is no entry for 1 bit values; gamma correction is never1500* significant.1501*/1502static const png_uint_16 gamma_threshold_by_sbit[15][2] =1503{1504{ 36907, 63092 }, /* 2 bits */1505{ 17812, 21518 }, /* 3 bits */1506{ 8675, 9496 }, /* 4 bits */1507{ 4290, 4484 }, /* 5 bits */1508{ 2134, 2181 }, /* 6 bits */1509{ 1064, 1075 }, /* 7 bits */1510{ 531, 534 }, /* 8 bits */1511{ 265, 266 }, /* 9 bits */1512{ 132, 132 }, /* 10 bits */1513{ 66, 66 }, /* 11 bits */1514{ 33, 33 }, /* 12 bits */1515{ 16, 16 }, /* 13 bits */1516{ 8, 8 }, /* 14 bits */1517{ 4, 4 }, /* 15 bits */1518{ 2, 2 }, /* 16 bits */1519};15201521/* Handle out of range values in release by doing the gamma correction: */1522debug_handled(sbits > 0U && sbits <= 16U);1523if (sbits == 0U || sbits > 16U)1524return 1;15251526/* 1 bit input or zero gamma, no correction possible/required: */1527if (gamma_val == 0 || sbits < 2U)1528return 0;15291530if (gamma_val < PNG_FP_1 - gamma_threshold_by_sbit[sbits-2U][0U])1531return gamma_val < PNG_FP_1 - png_ptr->gamma_threshold;15321533else if (gamma_val > PNG_FP_1 + gamma_threshold_by_sbit[sbits-2U][1U])1534return gamma_val > PNG_FP_1 + png_ptr->gamma_threshold;1535#else /* FIXUP */1536if (gamma_val < PNG_FP_1)1537return gamma_val < PNG_FP_1 - png_ptr->gamma_threshold;15381539else if (gamma_val > PNG_FP_1)1540return gamma_val > PNG_FP_1 + png_ptr->gamma_threshold;15411542PNG_UNUSED(sbits)1543#endif /* FIXUP */15441545return 0; /* not significant */1546}15471548static int1549png_gamma_equal(png_const_structrp png_ptr, png_fixed_point g1,1550png_fixed_point g2, png_fixed_point *c, unsigned int sbits)1551/* Gamma values are equal, or at least one is unknown; c is the correction1552* factor from g1 to g2, i.e. g2/g1.1553*/1554{1555return sbits == 1U || g1 == 0 || g2 == 0 || g1 == g2 ||1556(png_muldiv(c, g2, PNG_FP_1, g1) &&1557!png_gamma_significant(png_ptr, *c, sbits));1558}15591560#ifdef PNG_SIMPLIFIED_READ_SUPPORTED1561int1562png_need_gamma_correction(png_const_structrp png_ptr, png_fixed_point gamma,1563int sRGB_output)1564/* This is a hook for the simplified code; it just decides whether or not the1565* given gamma (which defaults to that of the PNG data) is close enough to1566* linear or sRGB not to require gamma correction.1567*/1568{1569if (gamma == 0)1570gamma = png_ptr->colorspace.gamma;15711572if (gamma != 0 &&1573(png_ptr->colorspace.flags &1574(PNG_COLORSPACE_INVALID|PNG_COLORSPACE_HAVE_GAMMA)) ==1575PNG_COLORSPACE_HAVE_GAMMA)1576{15771578if (sRGB_output && !png_muldiv(&gamma, gamma, PNG_GAMMA_sRGB, PNG_FP_1))1579return 0; /* overflow, so no correction */15801581return png_gamma_significant(png_ptr, gamma, (png_ptr->color_type &1582PNG_COLOR_MASK_PALETTE) ? 8U : png_ptr->bit_depth);1583}15841585return 0; /* no info, no correction */1586}1587#endif /* SIMPLIFIED_READ */15881589#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED1590/* Fixed point gamma.1591*1592* The code to calculate the tables used below can be found in the shell script1593* contrib/tools/intgamma.sh1594*1595* To calculate gamma this code implements fast log() and exp() calls using only1596* fixed point arithmetic. This code has sufficient precision for either 8-bit1597* or 16-bit sample values.1598*1599* The tables used here were calculated using simple 'bc' programs, but C double1600* precision floating point arithmetic would work fine.1601*1602* 8-bit log table1603* This is a table of -log(value/255)/log(2) for 'value' in the range 128 to1604* 255, so it's the base 2 logarithm of a normalized 8-bit floating point1605* mantissa. The numbers are 32-bit fractions.1606*/1607static const png_uint_321608png_8bit_l2[128] =1609{16104270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U,16113986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U,16123715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U,16133455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U,16143205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U,16152965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U,16162735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U,16172512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U,16182297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U,16192089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U,16201888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U,16211694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U,16221505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U,16231322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U,16241144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U,1625971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U,1626803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U,1627639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U,1628479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U,1629324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U,1630172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U,163124347096U, 0U16321633#if 0 /* NOT USED */1634/* The following are the values for 16-bit tables - these work fine for the1635* 8-bit conversions but produce very slightly larger errors in the 16-bit1636* log (about 1.2 as opposed to 0.7 absolute error in the final value). To1637* use these all the shifts below must be adjusted appropriately.1638*/163965166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054,164057371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803,164150170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068,164243479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782,164337230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887,164431369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339,164525850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098,164620636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132,164715694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415,164810997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523,16496127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495,16501119, 744, 3721651#endif1652};16531654#if 0 /* UNUSED */1655static png_int_321656png_log8bit(unsigned int x)1657{1658png_uint_32 lg2 = 0U;16591660/* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log,1661* because the log is actually negate that means adding 1. The final1662* returned value thus has the range 0 (for 255 input) to 7.994 (for 11663* input), return -1 for the overflow (log 0) case, - so the result is1664* always at most 19 bits.1665*/1666if ((x &= 0xffU) == 0U) /* 0 input, -inf output */1667return -0xfffff;16681669if ((x & 0xf0U) == 0U)1670lg2 = 4U, x <<= 4;16711672if ((x & 0xc0U) == 0U)1673lg2 += 2U, x <<= 2;16741675if ((x & 0x80U) == 0U)1676lg2 += 1U, x <<= 1;16771678/* result is at most 19 bits, so this cast is safe: */1679return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128U]+32768U)>>16));1680}1681#endif /* UNUSED */16821683/* The above gives exact (to 16 binary places) log2 values for 8-bit images,1684* for 16-bit images we use the most significant 8 bits of the 16-bit value to1685* get an approximation then multiply the approximation by a correction factor1686* determined by the remaining up to 8 bits. This requires an additional step1687* in the 16-bit case.1688*1689* We want log2(value/65535), we have log2(v'/255), where:1690*1691* value = v' * 256 + v''1692* = v' * f1693*1694* So f is value/v', which is equal to (256+v''/v') since v' is in the range 1281695* to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less1696* than 258. The final factor also needs to correct for the fact that our 8-bit1697* value is scaled by 255, whereas the 16-bit values must be scaled by 65535.1698*1699* This gives a final formula using a calculated value 'x' which is value/v' and1700* scaling by 65536 to match the above table:1701*1702* log2(x/257) * 655361703*1704* Since these numbers are so close to '1' we can use simple linear1705* interpolation between the two end values 256/257 (result -368.61) and 258/2571706* (result 367.179). The values used below are scaled by a further 64 to give1707* 16-bit precision in the interpolation:1708*1709* Start (256): -235911710* Zero (257): 01711* End (258): 234991712*1713* In libpng 1.7.0 this is further generalized to return -log2(value/maxval) for1714* any maxval up to 65535. This is done by evaluating -log2(value/65535) first1715* then adjusting for the required maxval:1716*1717* ( value) (value 65535) (value) ( 65535)1718* -log2(------) = -log2(----- x ------) = -log2(-----)-log2(------)1719* (maxval) (65535 maxval) (65535) (maxval)1720*1721* The extra argument, 'factor', is (2^(16+12))*log2(65535/maxval) (a positive1722* value less than 2^32) and this is *subtracted* from the intermediate1723* calculation below.1724*/1725static png_int_321726png_log(unsigned int x, png_uint_32 factor)1727/* x: a value of up to 16 bits,1728* factor: a 4.28 number which is subtracted from the log below1729*/1730{1731png_uint_32 lg2 = 0U;17321733/* As above, but now the input has 16 bits. */1734if ((x &= 0xffffU) == 0U)1735return -0xfffff;17361737if ((x & 0xff00U) == 0U)1738lg2 = 8U, x <<= 8;17391740if ((x & 0xf000U) == 0U)1741lg2 += 4U, x <<= 4;17421743if ((x & 0xc000U) == 0U)1744lg2 += 2U, x <<= 2;17451746if ((x & 0x8000U) == 0U)1747lg2 += 1U, x <<= 1;17481749/* Calculate the base logarithm from the top 8 bits as a 28-bit fractional1750* value.1751*/1752lg2 <<= 28;1753lg2 += (png_8bit_l2[(x>>8)-128U]+8U) >> 4;17541755/* Now we need to interpolate the factor, this requires a division by the top1756* 8 bits. Do this with maximum precision.1757*/1758{1759png_uint_32 i = x;17601761i = ((i << 16) + (i >> 9)) / (x>> 8);17621763/* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24,1764* the value at 1<<16 (ignoring this) will be 0 or 1; this gives us1765* exactly 16 bits to interpolate to get the low bits of the result.1766* Round the answer. Note that the end point values are scaled by 64 to1767* retain overall precision and that 'lg2' is current scaled by an extra1768* 12 bits, so adjust the overall scaling by 6-12. Round at every step.1769*/1770i -= 1U << 24;17711772if (i <= 65536U) /* <= '257' */1773lg2 += ((23591U * (65536U-i)) + (1U << (16+6-12-1))) >> (16+6-12);17741775else1776lg2 -= ((23499U * (i-65536U)) + (1U << (16+6-12-1))) >> (16+6-12);1777}17781779if (lg2 >= factor)1780return (png_int_32)/*SAFE*/((lg2 - factor + 2048U) >> 12);17811782else /* the result will be greater than 1.0, so negative: */1783return -(png_int_32)/*SAFE*/((factor - lg2 + 2048U) >> 12);1784}17851786#if 0 /* UNUSED */1787static png_int_321788png_log16bit(unsigned int x)1789{1790return png_log(x, 0U);1791}1792#endif /* UNUSED */17931794/* libpng 1.7.0: generalization of png_log{8,16}bit to accept an n-bit input1795* value. We want to maintain 1% accuracy in linear light space. This1796* corresponds to, approximately, (1*g)% in a gamma encoded space where the1797* gamma encoding is 'g' (in the PNG sense, e.g. 0.45455 for sRGB). Apparently1798* this requires unbounded accuracy as the gamma encoding value goes down and1799* this is a problem for modern HDR data because it may require a high gamma to1800* accurately encode image data over a wide dynamic range; the dynamic range of1801* 16-bit linear data is only 655:1 if 1% accuracy is needed!1802*1803* However 16-bit gamma encoded data is still limited because PNG can only1804* express gamma encoding. (A log-to-base-1.01 encoding is unlimited; a 12-bit1805* value, with 4094 steps, has a dynamic range of more than 1:10^17, which1806* exceeds the human eye's range of 1:10^14.)1807*1808* Notice that sRGB uses a 1/2.4 encoding and CIELab uses a 1/3 encoding. It is1809* obvious that, if we assume a maximum D difference in the luminance of1810* adjacent pixel values the dynamic range is given by the lowest pixel value1811* which is D or less greater than its predecessor, so:1812*1813* ( P ) (1)1814* (---)^(-) = D1815* (P-1) (g)1816*1817* and the maximum dynamic range that can be achieved using M+1 separate values,1818* where M+1 is 2^N-1 for an N bit value, reserving the first value for 0, is:1819*1820* (M) (1)1821* range(R) = (-)^(-)1822* (P) (g)1823*1824* So we can eliminate 'P' from the two equations:1825*1826* P = (P-1) x (D^g)1827*1828* D^g1829* P = -----1830* D^g-11831*1832* (M x (D^g-1)) (1)1833* R = (-----------)^(-)1834* ( D^g ) (g)1835*1836* (M x (D^g-1)) ^ (1/g)1837* = ---------------------1838* D1839*1840* Which is a function in two variables (R and g) for a given D (maximum delta1841* between two adjacent pixel values) and M (number of pixel values, controlled1842* by the channel bit depth).1843*1844* See contrib/tools/dynamic-range.c for code exploring this function. This1845* program will output the optimal gamma for a given number of bits and1846* precision.1847*1848* The range of sensitivity of human vision is roughly as follows (this comes1849* from the wikipedia article on scotopic vision):1850*1851* scotopic: 10^-6 to 10^-3.5 cd/m^21852* mesopic: 10^-3 to 10^0.5 cd/m^21853* photopic: 10 to 10^8 cd/m^21854*1855* Giving a total range of about 1:10^14. The maximum precision at which this1856* range can be achieved using 16-bit channels is about .15% using a gamma of1857* 36, higher ranges are possible using higher gammas but precision is reduced.1858* The range with 1% precision and 16-bit channels is 1:10^104, using a gamma of1859* 240.1860*1861* In general the optimal gamma for n-bit channels (where 'n' is at least 7 and1862* precision is .01 or less) is:1863*1864* 2^n * precision1865* gamma = ---------------1866* 2.7361867*1868* Or: (24000 * precision) for 16-bit data.1869*1870* The net effect is that we can't rely on the encoding gamma being limited to1871* values around 1/2.5!1872*/1873static png_int_321874png_log_nbit(unsigned int x, unsigned int nbits)1875{1876static const png_uint_32 factors[16] =1877{18784294961387U, /* 1 bit */18793869501255U, /* 2 bit */18803541367788U, /* 3 bit */18813246213428U, /* 4 bit */18822965079441U, /* 5 bit */18832690447525U, /* 6 bit */18842418950626U, /* 7 bit */18852148993476U, /* 8 bit */18861879799410U, /* 9 bit */18871610985205U, /* 10 bit */18881342360514U, /* 11 bit */18891073830475U, /* 12 bit */1890805347736U, /* 13 bit */1891536888641U, /* 14 bit */1892268441365U, /* 15 bit */18930U /* 16 bit */1894};18951896return png_log(x, factors[nbits-1]);1897}189818991900/* The 'exp()' case must invert the above, taking a 20-bit fixed point1901* logarithmic value and returning a 16 or 8-bit number as appropriate. In1902* each case only the low 16 bits are relevant - the fraction - since the1903* integer bits (the top 4) simply determine a shift.1904*1905* The worst case is the 16-bit distinction between 65535 and 65534. This1906* requires perhaps spurious accuracy in the decoding of the logarithm to1907* distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance1908* of needing this accuracy in practice.1909*1910* To deal with this the following exp() function works out the exponent of the1911* frational part of the logarithm by using an accurate 32-bit value from the1912* top four fractional bits then multiplying in the remaining bits.1913*/1914static const png_uint_321915png_32bit_exp[16] =1916{1917/* NOTE: the first entry is deliberately set to the maximum 32-bit value. */19184294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U,19193311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U,19202553802834U, 2445529972U, 2341847524U, 2242560872U1921};19221923/* Adjustment table; provided to explain the numbers in the code below. */1924#if 0 /* BC CODE */1925for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"}192611 44937.64284865548751208448192710 45180.9873484558510116044819289 45303.3193698068735931187219298 45364.6511059532301887078419307 45395.3585036178962461491219316 45410.7225971510203750809619325 45418.4072441322072231116819334 45422.2502178689817300172819343 45424.1718673229841904435219352 45425.1327326994081146470419361 45425.6131755503555864166419370 45425.853399516549438504961938#endif19391940static png_uint_321941png_exp(png_int_32 x)1942/* Utility, the value 'x' must be in the range 0..0x1fffff */1943{1944/* Obtain a 4-bit approximation */1945png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf];19461947/* Incorporate the low 12 bits - these decrease the returned value by1948* multiplying by a number less than 1 if the bit is set. The multiplier1949* is determined by the above table and the shift. Notice that the values1950* converge on 45426 and this is used to allow linear interpolation of the1951* low bits.1952*/1953if (x & 0x800)1954e -= (((e >> 16) * 44938U) + 16U) >> 5;19551956if (x & 0x400)1957e -= (((e >> 16) * 45181U) + 32U) >> 6;19581959if (x & 0x200)1960e -= (((e >> 16) * 45303U) + 64U) >> 7;19611962if (x & 0x100)1963e -= (((e >> 16) * 45365U) + 128U) >> 8;19641965if (x & 0x080)1966e -= (((e >> 16) * 45395U) + 256U) >> 9;19671968if (x & 0x040)1969e -= (((e >> 16) * 45410U) + 512U) >> 10;19701971/* And handle the low 6 bits in a single block. */1972e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9;19731974/* Handle the upper bits of x, note that this works for x up to 0x1fffff but1975* fails for larger or negative x, where the shift (x >> 16) exceeds 31:1976*/1977e >>= x >> 16;1978return e;1979}19801981#if 0 /* UNUSED */1982static png_byte1983png_exp8bit(png_int_32 lg2)1984{1985/* The input is a negative fixed point (16:16) logarithm with a useable range1986* of [0.0..8.0). Clamp the value so that the output of png_exp is in the1987* range (254.5/255..0.5/255):1988*/1989if (lg2 <= 185) /* -log2(254.5/255) */1990return 255U;19911992else if (lg2 > 589453) /* -log2(0.5/255) */1993return 0U;19941995else1996{1997/* Get a 32-bit value: */1998png_uint_32 x = png_exp(lg2);19992000/* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that2001* the second, rounding, step can't overflow because of the first,2002* subtraction, step.2003*/2004x -= x >> 8;2005return PNG_BYTE((x + 0x7fffffU) >> 24);2006}2007}20082009static png_uint_162010png_exp16bit(png_int_32 lg2)2011{2012if (lg2 <= 0) /* -log2(65534.5/65535) */2013return 65535U;20142015else if (lg2 > 1114110) /* -log2(0.5/65535) */2016return 0U;20172018else2019{2020/* Get a 32-bit value: */2021png_uint_32 x = png_exp(lg2);20222023/* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */2024x -= x >> 16;2025return PNG_UINT_16((x + 32767U) >> 16);2026}2027}2028#endif /* UNUSED */20292030static png_uint_322031png_exp_nbit(png_int_32 lg2, unsigned int n)2032{2033/* These pre-computed limits give the low value of lg2 at and below which2034* 2^(-lg2/65536) * (2^n-1) gives (2^n-1) and the high value of lg2 above2035* which 2(^-lg2/65536) * (2^n-1) gives 0:2036*/2037static const png_int_32 limits[16][2] =2038{2039{ 65535, 65535 }, /* bits = 1 */2040{ 17238, 169408 }, /* bits = 2 */2041{ 7006, 249518 }, /* bits = 3 */2042{ 3205, 321577 }, /* bits = 4 */2043{ 1537, 390214 }, /* bits = 5 */2044{ 753, 457263 }, /* bits = 6 */2045{ 372, 523546 }, /* bits = 7 */2046{ 185, 589453 }, /* bits = 8 */2047{ 92, 655175 }, /* bits = 9 */2048{ 46, 720803 }, /* bits = 10 */2049{ 23, 786385 }, /* bits = 11 */2050{ 11, 851944 }, /* bits = 12 */2051{ 5, 917492 }, /* bits = 13 */2052{ 2, 983034 }, /* bits = 14 */2053{ 1, 1048573 }, /* bits = 15 */2054{ 0, 1114110 } /* bits = 16 */2055};20562057/* If 'max' is 2^n-1: */2058if (lg2 <= limits[n-1][0]) /* -log2((max-.5)/max) */2059return (1U << n)-1U;20602061else if (lg2 > limits[n-1][1]) /* -log2(.5/max) */2062return 0U;20632064else /* 'n' will be at least 2 */2065{2066/* Get a 32-bit value: */2067png_uint_32 x = png_exp(lg2);20682069/* Convert the 32-bit value to 0..(2^n-1) by multiplying by 2^n-1: */2070x -= x >> n;2071return (x + ((1U<<(31U-n))-1U)) >> (32U-n);2072}2073}2074#endif /* !FLOATING_ARITHMETIC */20752076#if 0 /* UNUSED */2077static png_byte2078png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)2079{2080if (value == 0U)2081return 0U;20822083else if (value >= 255U)2084return 255U;20852086else2087{2088# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED2089/* 'value' is unsigned, ANSI-C90 requires the compiler to correctly2090* convert this to a floating point value. This includes values that2091* would overflow if 'value' were to be converted to 'int'.2092*2093* Apparently GCC, however, does an intermediate conversion to (int)2094* on some (ARM) but not all (x86) platforms, possibly because of2095* hardware FP limitations. (E.g. if the hardware conversion always2096* assumes the integer register contains a signed value.) This results2097* in ANSI-C undefined behavior for large values.2098*2099* Other implementations on the same machine might actually be ANSI-C902100* conformant and therefore compile spurious extra code for the large2101* values.2102*2103* We can be reasonably sure that an unsigned to float conversion2104* won't be faster than an int to float one. Therefore this code2105* assumes responsibility for the undefined behavior, which it knows2106* can't happen because of the check above.2107*2108* Note the argument to this routine is an (unsigned int) because, on2109* 16-bit platforms, it is assigned a value which might be out of2110* range for an (int); that would result in undefined behavior in the2111* caller if the *argument* ('value') were to be declared (int).2112*/2113double r = 255*pow((int)/*SAFE*/value/255.,gamma_val*.00001);2114if (r < .5)2115return 0U;21162117else if (r >= 254.5)2118return 255U;21192120r = floor(r+.5);2121return (png_byte)/*SAFE*/r;2122# else2123png_int_32 lg2 = png_log8bit(value);2124png_int_32 res;21252126/* Overflow in the muldiv means underflow in the calculation, this is2127* OK (it happens for ridiculously high gamma).2128*/2129if (!png_muldiv(&res, gamma_val, lg2, PNG_FP_1))2130return 0U; /* underflow */21312132return png_exp8bit(res);2133# endif2134}2135}2136#endif /* UNUSED */21372138/* libpng-1.7.0: this private function converts an n-bit input value to an2139* m-bit output value.2140*/2141unsigned int2142png_gamma_nxmbit_correct(unsigned int value, png_fixed_point gamma_val,2143unsigned int n/*input bits*/, unsigned int m/*output bits */)2144{2145if (value == 0U)2146return 0U;21472148else2149{2150unsigned int min = (1U<<n) - 1U;2151unsigned int mout = (1U<<m) - 1U;21522153if (value >= min)2154return mout;21552156else2157{2158# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED2159double r = value;2160r /= min;2161r = floor(mout * pow(r, gamma_val*.00001)+.5);2162if (r < 1)2163return 0U;21642165else if (r >= mout)2166return mout;21672168return (unsigned int)/*SAFE*/r;2169# else2170png_int_32 lg2 = png_log_nbit(value, n);2171png_int_32 res;21722173if (!png_muldiv(&res, gamma_val, lg2, PNG_FP_1))2174return 0U; /* underflow */21752176return png_exp_nbit(res, m);2177# endif2178}2179}2180}21812182#if 0 /*UNUSED*/2183static unsigned int2184png_gamma_sbit_correct(unsigned int value, png_fixed_point gamma_val,2185unsigned int n/*input bits*/, unsigned int sbits,2186unsigned int m/*output bits */)2187/* As above but the number of significant bits in 'n' is passed in. */2188{2189if (sbits < n)2190{2191value >>= (n-sbits);2192n = sbits;2193}21942195return png_gamma_nxmbit_correct(value, gamma_val, n, m);2196}2197#endif /*UNUSED*/21982199static int2200push_gamma_expand(png_transformp *transform, png_transform_controlp tc,2201int need_alpha)2202/* Utility to push a transform to expand low-bit-depth gray and, where2203* required, tRNS chunks. The caller must return immediately if this2204* returns true because the init of the new transform has been run in place2205* of the caller's.2206*/2207{2208# define png_ptr (tc->png_ptr)2209unsigned int expand = 0;22102211affirm(tc->init == PNG_TC_INIT_FINAL);22122213if (tc->bit_depth < 8U) /* low bit gray: expand to 8 bits */2214expand = PNG_EXPAND_LBD_GRAY;22152216/* Gamma correction invalidates tRNS, so if it is being expanded and2217* alpha is not being stripped expand it now.2218*/2219if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0 && !tc->palette &&2220png_ptr->num_trans == 1 && (tc->invalid_info & PNG_INFO_tRNS) == 0)2221{2222if (need_alpha || (tc->expand_tRNS && !tc->strip_alpha))2223expand |= PNG_EXPAND_tRNS;22242225else2226tc->invalid_info |= PNG_INFO_tRNS;2227}22282229if (expand == 0)2230return 0; /* nothing needs to be done */22312232{2233png_transformp tr = png_push_transform(png_ptr, sizeof (png_expand),2234png_init_expand, transform, NULL/*don't run init*/);22352236debug(tr == *transform);2237tr->args |= expand;22382239/* This must be run immediately, because it just got inserted where this2240* transform is; this is safe, the caller must return immediately.2241*/2242png_init_expand(transform, tc);2243affirm(tr->fn != NULL); /* because it should need to do something! */2244}22452246return 1;2247# undef png_ptr2248}22492250/* Low bit depth gray gamma correction. The 1-bit case is a no-op because 0 and2251* 1 always map to 0 and 1. The 2-bit case has the following possiblities:2252*2253* bits/correction: g0 g1 g2 g3 g4 g5 g62254* 00 -> 00 00 00 00 00 00 002255* 01 -> 11 10 10 01 00 00 002256* 10 -> 11 11 10 10 10 01 002257* 11 -> 11 11 11 11 11 11 112258*2259* Where the breakpoints are:2260*2261* g0: correction <= 16595 (1 - log(2.5/3))2262* g1: 16595 < correction <= 44966 (log(2.5/3)/log(2/3))2263* g2: 44966 < correction <= 63092 (1 - log(1.5/3))2264* g3: 63092 < correction <= 163092 (1 - log(.5/3))2265* g4: 163092 < correction <= 170951 (log(1.5/3)/log(2/3))2266* g5: 170951 < correction <= 441902 (log(.5/3)/log(2/3)2267* g6 441902 < correction2268*2269* This can be done by bit-hacking on the byte values (4 pixels), given that2270* the correction is fixed (indeed, it can be done on whole 32-bit values!)2271*2272* g0: B |= B>>1; B &= 0x55U; B |= B<<1; * either bit set2273* g1: B ^= B>>1; B &= 0x55U; B += B; * one bit set2274* g2: B &= (~B)>>1; B &= 0x55U; B += B; * low bit set, high bit unset2275* g3: no-op2276* g4: B &= (~B)>>1; B &= 0x55U; B -= B; * low bit set, high bit unset2277* g5: B ^= B>>1; B &= 0x55U; B -= B; * one bit set2278* g6: B &= B>>1; B &= 0x55U; B |= B<<1; * both bits set2279*/2280typedef struct2281{2282png_transform tr;2283png_fixed_point correct;2284png_fixed_point to_gamma;2285png_uint_32 shifts; /* 1 followed by up to 4 4-bit shifts */2286png_uint_32 channel_scale[4]; /* up to 4 channel scale factors */2287/* These factors are used:2288*2289* (input >> (shifts & 0xFU) * channel_scale + SCALE_R) >> SCALE_S2290*2291* Where the rounding value, SCALE_R and the shift SCALE_S are dependent2292* on the bit depth:2293*2294* SCALE_S = 32 - bit_depth range 16..312295* SCALE_R = 1 << (SCALE_S-1)2296*/2297unsigned int to_bit_depth;2298unsigned int encode_alpha :1;2299unsigned int optimize_alpha :1;2300} png_transform_gamma;23012302static unsigned int2303init_gamma_sBIT(png_transform_gamma *tr, png_transform_controlp tc)2304/* Returns true if sBIT processing is required, otherwise all relevant sBIT2305* values match the from (tc) bit depth.2306*/2307{2308/* The to_bit_depth and to_gamma fields are already set, but updated values2309* are needed for sBIT and the shifts and channel_scale fields must be filled2310* in correctly. The do_gamma setting says whether gamma correction will be2311* done, but the scale factors are filled in regardless.2312*2313* The general scaling equation is:2314*2315* ((in >> shift) * factor + round) >> (32 - to_bit_depth)2316*2317* 'factor' is then the rounded value of:2318*2319* out_max2320* ------- . (1 << (32-to_bit_depth))2321* in_max2322*/2323# define png_ptr (tc->png_ptr)2324const unsigned int to_bit_depth = tr->to_bit_depth;2325const png_uint_32 numerator = ((1U<<to_bit_depth)-1U) << (32U-to_bit_depth);2326/* in_max depends on the number of significant bits */2327const unsigned int from_bit_depth = tc->bit_depth;23282329/* The data in the gamma transform is stored in the order of the channels in2330* the input row, which is the PNG order. It may be reversed below.2331*/2332png_uint_32p channel_scale = tr->channel_scale;2333png_uint_32 shifts = 0U;2334unsigned int count = 0U;2335unsigned int need_sBIT = 0U;23362337if (tc->format & PNG_FORMAT_FLAG_COLOR)2338{2339const unsigned int sBIT = tc->sBIT_R;23402341if (sBIT < from_bit_depth)2342need_sBIT = 1U;23432344debug(sBIT > 0U && sBIT <= from_bit_depth);2345shifts |= (from_bit_depth - sBIT) << count;2346count += 4U;2347/* round the scale: */2348*channel_scale++ = (numerator + (1U<<(sBIT-1U))) / ((1U << sBIT)-1U);2349}23502351{2352const unsigned int sBIT = tc->sBIT_G;23532354if (sBIT < from_bit_depth)2355need_sBIT = 1U;23562357debug(sBIT > 0U && sBIT <= from_bit_depth);2358shifts |= (from_bit_depth - sBIT) << count;2359count += 4U;2360*channel_scale++ = (numerator + (1U<<(sBIT-1U))) / ((1U << sBIT)-1U);2361}23622363if (tc->format & PNG_FORMAT_FLAG_COLOR)2364{2365const unsigned int sBIT = tc->sBIT_B;23662367if (sBIT < from_bit_depth)2368need_sBIT = 1U;23692370debug(sBIT > 0U && sBIT <= from_bit_depth);2371shifts |= (from_bit_depth - sBIT) << count;2372count += 4U;2373/* round the scale: */2374*channel_scale++ = (numerator + (1U<<(sBIT-1U))) / ((1U << sBIT)-1U);2375}23762377if (tc->format & PNG_FORMAT_FLAG_ALPHA)2378{2379const unsigned int sBIT = tc->sBIT_A;23802381if (sBIT < from_bit_depth)2382need_sBIT = 1U;23832384debug(sBIT > 0U && sBIT <= from_bit_depth);2385shifts |= (from_bit_depth - sBIT) << count;2386count += 4U;2387/* round the scale: */2388*channel_scale++ = (numerator + (1U<<(sBIT-1U))) / ((1U << sBIT)-1U);2389}23902391tr->shifts = shifts | (1U << count);23922393return need_sBIT;2394# undef png_ptr2395}23962397static void2398reverse_gamma_sBIT(png_transform_gamma *tr)2399{2400/* This is called for the 'down' gamma implementations, they read the shifts2401* and the channel scales in reverse, so:2402*/2403png_uint_32 shifts = tr->shifts;2404png_uint_32 scales[4U];2405unsigned int count = 0U;24062407tr->shifts = 1U;24082409while (shifts != 1U)2410{2411scales[3U-count] = tr->channel_scale[count];2412++count;2413tr->shifts <<= 4;2414tr->shifts |= shifts & 0xFU;2415shifts >>= 4;2416}24172418memcpy(tr->channel_scale, scales+(4U-count), count * sizeof (png_uint_32));2419}24202421static void2422png_do_gamma8_up(png_transformp *transform, png_transform_controlp tc)2423{2424# define png_ptr (tc->png_ptr)2425png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);2426png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc);2427png_bytep dp = png_voidcast(png_bytep, tc->dp);2428png_transform_gamma *tr =2429png_transform_cast(png_transform_gamma, *transform);2430const png_fixed_point correct = tr->correct;2431const unsigned int bit_depth = tr->to_bit_depth;2432const png_uint_32 shifts = tr->shifts;24332434affirm(tc->bit_depth == 8U);2435affirm(tr->shifts != 0U/*uninitialized*/);2436debug((shifts & 0x8888U) == 0U); /* all shifts 7 or less */2437debug(!tr->encode_alpha && !tr->optimize_alpha); /* only set for 16 bits */24382439tc->sp = dp;2440tc->bit_depth = bit_depth;2441tc->gamma = tr->to_gamma;24422443/* Handle the <8 bit output case differently because there can be no alpha2444* channel.2445*/2446if (bit_depth < 8U)2447{2448const unsigned int shift = shifts & 0xFU;2449unsigned int bits = 8U;2450unsigned int ob = 0U;24512452debug((shifts >> 4) == 1U && shift < 8U);2453affirm(PNG_TC_CHANNELS(*tc) == 1);24542455do2456{2457const unsigned int inb = png_gamma_nxmbit_correct(2458*sp++ >> shift, correct, 8U-shift, bit_depth);2459bits -= bit_depth;2460ob = ob | (inb << bits);2461if (bits == 0U)2462bits = 8U, *dp++ = PNG_BYTE(ob), ob = 0U;2463}2464while (sp < ep);24652466if (bits < 8U)2467*dp++ = PNG_BYTE(ob);2468}24692470else /* 8-bit --> 8-bit */2471{2472png_uint_32 alpha_scale;2473const unsigned int channels = PNG_TC_CHANNELS(*tc);2474unsigned int channel, alpha;24752476debug(bit_depth == 8U && (shifts >> (4*channels)) == 1U);24772478/* The alpha channel is always last, so if present checking against the2479* top bits of 'channels' works because of the 1U shibboleth at the end.2480*/2481if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0)2482alpha_scale = alpha = 0U;24832484else2485{2486alpha = shifts >> (4U*(channels-1U));2487alpha_scale = tr->channel_scale[channels-1U];2488}24892490channel = 1U;24912492do2493{2494unsigned int inb = *sp++, shift;24952496if (channel == 1U)2497channel = shifts;24982499shift = channel & 0xFU;2500inb >>= shift;25012502/* The alpha channel is not gamma encoded but it may need some2503* appropriate scaling.2504*/2505if (channel == alpha)2506inb = (inb * alpha_scale + 0x800000U) >> 24;25072508else2509inb = png_gamma_nxmbit_correct(inb, correct, 8U-shift, 8U);25102511channel >>= 4; /* for the next channel, or the shibboleth */2512*dp++ = PNG_BYTE(inb);2513}2514while (sp < ep);25152516debug(channel == 1U);2517}2518# undef png_ptr2519}25202521static void2522png_do_gamma16_up(png_transformp *transform, png_transform_controlp tc)2523{2524# define png_ptr (tc->png_ptr)2525png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);2526png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 1U/*safety*/;2527png_bytep dp = png_voidcast(png_bytep, tc->dp);2528png_transform_gamma *tr =2529png_transform_cast(png_transform_gamma, *transform);2530const png_fixed_point correct = tr->correct;2531const unsigned int bit_depth = tr->to_bit_depth;2532const png_uint_32 shifts = tr->shifts;25332534affirm(tc->bit_depth == 16U);2535affirm(tr->shifts != 0U/*uninitialized*/);2536debug(!tr->optimize_alpha);25372538/* This is exactly the same as above but the input has 16 bits per component,2539* not 8.2540*/2541tc->sp = dp;2542tc->bit_depth = bit_depth;2543tc->gamma = tr->to_gamma;25442545/* Handle the <8 bit output case differently, the input cannot be color (at2546* present) and, if there is an alpha channel, then it is for the2547* low-bit-depth gray input case and we expect the alpha to be transparent.2548*/2549if (bit_depth < 8U)2550{2551const unsigned int shift = shifts & 0xFU;2552unsigned int bits = 8U;2553unsigned int ob = 0U;25542555affirm((tc->format & PNG_FORMAT_FLAG_COLOR) == 0U);25562557if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0U)2558{2559debug((shifts >> 4) == 1U && shift < 16U);2560debug(!tr->encode_alpha && !tr->optimize_alpha);25612562do2563{2564unsigned int inb = *sp++ << 8; /* high bits first */2565inb = png_gamma_nxmbit_correct(2566(inb + *sp++) >> shift, correct, 16U-shift, bit_depth);25672568bits -= bit_depth;2569ob = ob | (inb << bits);2570if (bits == 0U)2571bits = 8U, *dp++ = PNG_BYTE(ob), ob = 0U;2572}2573while (sp < ep);25742575UNTESTED2576}25772578else /* low bit GA intermediate format */2579{2580debug((shifts >> 8) == 1U && shift < 16U);2581debug(!tr->encode_alpha && !tr->optimize_alpha);2582debug(tc->transparent_alpha);25832584/* Gray is first then the alpha component, the alpha component is just2585* mapped to 0 or 1.2586*/2587do2588{2589unsigned int gray = *sp++ << 8; /* high bits first */2590unsigned int alpha;2591gray += *sp++;25922593alpha = (*sp++ << 8);2594alpha += *sp++;25952596if (alpha == 0U)2597gray = 0U; /* will be replaced later */25982599else2600{2601gray = png_gamma_nxmbit_correct(gray >> shift, correct,260216U-shift, bit_depth);2603debug(alpha == 65535U);2604alpha = (1U << bit_depth)-1U;2605}26062607bits -= bit_depth;2608ob = ob | (gray << bits);2609bits -= bit_depth;2610ob = ob | (alpha << bits);26112612if (bits == 0U)2613bits = 8U, *dp++ = PNG_BYTE(ob), ob = 0U;2614}2615while (sp < ep-2U);2616}26172618if (bits < 8U)2619*dp++ = PNG_BYTE(ob);26202621debug(sp == ep+1U);2622}26232624else2625{2626png_uint_32 alpha_scale;2627const unsigned int channels = PNG_TC_CHANNELS(*tc);2628unsigned int channel, alpha;26292630debug((bit_depth == 8U || bit_depth == 16U) &&2631(shifts >> (4*channels)) == 1U);26322633/* Note that 'encode_alpha' turns on gamma encoding of the alpha2634* channel (and this is a really weird operation!)2635*/2636if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0 || tr->encode_alpha)2637alpha_scale = alpha = 0U;26382639else2640{2641alpha = shifts >> (4U*(channels-1U));2642alpha_scale = tr->channel_scale[channels-1U];2643}26442645channel = 1U;26462647if (bit_depth == 16U)2648{2649do2650{2651unsigned int inb = *sp++ << 8, shift;2652inb += *sp++;26532654if (channel == 1U)2655channel = shifts;26562657shift = channel & 0xFU;2658inb >>= shift;26592660/* The 16-16bit scaling factor equation may be off-by-1 but this2661* hardly matters for alpha or for gamma operations.2662*/2663if (channel == alpha)2664inb = (inb * alpha_scale + 0x8000U) >> 16;26652666else2667inb = png_gamma_nxmbit_correct(inb, correct, 16U-shift, 16U);26682669channel >>= 4; /* for the next channel, or the shibboleth */2670*dp++ = PNG_BYTE(inb >> 8);2671*dp++ = PNG_BYTE(inb);2672}2673while (sp < ep);26742675debug(channel == 1U && sp == ep+1U);2676}26772678else /* bit_depth == 8U */2679{2680do2681{2682unsigned int inb = *sp++ << 8, shift;2683inb += *sp++;26842685if (channel == 1U)2686channel = shifts;26872688shift = channel & 0xFU;2689inb >>= shift;26902691if (channel == alpha)2692inb = (inb * alpha_scale + 0x800000U) >> 24;26932694else2695inb = png_gamma_nxmbit_correct(inb, correct, 16U-shift, 8U);26962697channel >>= 4; /* for the next channel, or the shibboleth */2698*dp++ = PNG_BYTE(inb);2699}2700while (sp < ep);27012702debug(channel == 1U && sp == ep+1U);2703}2704}2705# undef png_ptr2706}27072708#ifdef PNG_READ_ALPHA_MODE_SUPPORTED2709static void2710png_do_gamma16_up_optimize(png_transformp *transform, png_transform_controlp tc)2711/* As above, but the alpha channel is 'optimized' */2712{2713# define png_ptr (tc->png_ptr)2714png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);2715png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc);2716png_bytep dp = png_voidcast(png_bytep, tc->dp);2717png_transform_gamma *tr =2718png_transform_cast(png_transform_gamma, *transform);2719const png_fixed_point correct = tr->correct;27202721/* The input always as 16 bits, the output 8 or 16. There is always an alpha2722* channel and it is converted to the 'optimized' form, where pixels with2723* alpha not 0.0 or 1.0 are left in linear form (not gamma corrected.) Where2724* bit depth convertion is required it is from 16-bits to 8-bits and the2725* DIV257 macro can be used.2726*2727* The following affirms and NOT_REACHED cases are consequences of the way2728* the background (compose) code works:2729*/2730affirm(tr->optimize_alpha && !tr->encode_alpha && tc->bit_depth == 16U);27312732/* TODO: split this into separate functions */2733switch (tr->to_bit_depth)2734{2735case 8U: /* 16-bit --> 8-bit */2736tc->sp = dp;2737tc->bit_depth = 8U;2738tc->gamma = tr->to_gamma;27392740switch (PNG_TC_CHANNELS(*tc))2741{2742case 2:/* GA */2743debug(tr->shifts == 0x100U);2744ep -= 3U; /*SAFETY*/27452746do2747{2748png_uint_32 alpha = PNG_DIV257((sp[2] << 8) + sp[3]);27492750switch (alpha)2751{2752case 0U:2753dp[1] = dp[0] = 0U;2754break;27552756default: /* optimized case: linear color data */2757dp[0] = png_check_byte(png_ptr,2758PNG_DIV257((sp[0] << 8) + sp[1]));2759dp[1] = PNG_BYTE(alpha);2760break;27612762case 255U: /* opaque pixels are encoded */2763dp[0] = PNG_BYTE(png_gamma_nxmbit_correct(2764(sp[0] << 8) + sp[1], correct, 16U, 8U));2765dp[1] = 255U;2766break;2767}27682769sp += 4U;2770dp += 2U;2771}2772while (sp < ep);27732774debug(sp == ep+3U);2775break;27762777case 4:/* RGBA */2778debug(tr->shifts == 0x10000U);2779ep -= 7U; /*SAFETY*/27802781do2782{2783png_uint_32 alpha = PNG_DIV257((sp[6] << 8) + sp[7]);27842785switch (alpha)2786{2787case 0U:2788memset(dp, 0U, 4U);2789break;27902791default: /* optimized case: linear color data */2792dp[0] = PNG_BYTE(PNG_DIV257((sp[0] << 8) + sp[1]));2793dp[1] = PNG_BYTE(PNG_DIV257((sp[2] << 8) + sp[3]));2794dp[2] = PNG_BYTE(PNG_DIV257((sp[4] << 8) + sp[5]));2795dp[3] = PNG_BYTE(alpha);2796break;27972798case 255U: /* opaque pixels are encoded */2799dp[0] = PNG_BYTE(png_gamma_nxmbit_correct(2800(sp[0] << 8) + sp[1], correct, 16U, 8U));2801dp[1] = PNG_BYTE(png_gamma_nxmbit_correct(2802(sp[2] << 8) + sp[3], correct, 16U, 8U));2803dp[2] = PNG_BYTE(png_gamma_nxmbit_correct(2804(sp[4] << 8) + sp[5], correct, 16U, 8U));2805dp[3] = 255U;2806break;2807}28082809sp += 8U;2810dp += 4U;2811}2812while (sp < ep);28132814debug(sp == ep+7U);2815break;28162817default:2818NOT_REACHED;2819break;2820}2821break;28222823case 16: /* 16-bit to 16-bit */2824tc->sp = dp;2825tc->bit_depth = 16U;2826tc->gamma = tr->to_gamma;28272828switch (PNG_TC_CHANNELS(*tc))2829{2830case 2:/* GA */2831debug(tr->shifts == 0x100U);2832ep -= 3U; /*SAFETY*/28332834do2835{2836unsigned int alpha = (sp[2] << 8) + sp[3];28372838switch (alpha)2839{2840case 0U:2841memset(dp, 0U, 4U);2842break;28432844default: /* optimized case: linear color data */2845if (dp != sp)2846{2847memcpy(dp, sp, 4U);2848UNTESTED2849}2850break;28512852case 65535U: /* opaque pixels are encoded */2853{2854unsigned int gray = png_gamma_nxmbit_correct(2855(sp[0] << 8) + sp[1], correct, 16U, 16U);2856dp[0] = PNG_BYTE(gray >> 8);2857dp[1] = PNG_BYTE(gray);2858}2859dp[3] = dp[2] = 255U;2860break;2861}28622863sp += 4U;2864dp += 4U;2865}2866while (sp < ep);28672868debug(sp == ep+3U);2869break;28702871case 4:/* RGBA */2872debug(tr->shifts == 0x10000U);2873ep -= 7U; /*SAFETY*/28742875do2876{2877unsigned int alpha = (sp[6] << 8) + sp[7];28782879switch (alpha)2880{2881case 0U:2882memset(dp, 0U, 8U);2883break;28842885default: /* optimized case: linear color data */2886if (dp != sp)2887{2888memcpy(dp, sp, 8U);2889UNTESTED2890}2891break;28922893case 65535U: /* opaque pixels are encoded */2894{2895unsigned int c = png_gamma_nxmbit_correct(2896(sp[0] << 8) + sp[1], correct, 16U, 16U);2897dp[0] = PNG_BYTE(c >> 8);2898dp[1] = PNG_BYTE(c);28992900c = png_gamma_nxmbit_correct(2901(sp[2] << 8) + sp[3], correct, 16U, 16U);2902dp[2] = PNG_BYTE(c >> 8);2903dp[3] = PNG_BYTE(c);29042905c = png_gamma_nxmbit_correct(2906(sp[4] << 8) + sp[5], correct, 16U, 16U);2907dp[4] = PNG_BYTE(c >> 8);2908dp[5] = PNG_BYTE(c);2909}2910dp[7] = dp[6] = 255U;2911break;2912}29132914sp += 8U;2915dp += 8U;2916}2917while (sp < ep);29182919debug(sp == ep+7U);2920break;29212922default:2923NOT_REACHED;2924break;2925}2926break;29272928default:2929NOT_REACHED;2930break;2931}2932# undef png_ptr2933}2934#endif /* READ_ALPHA_MODE */29352936static void2937png_do_scale16_up(png_transformp *transform, png_transform_controlp tc)2938{2939# define png_ptr (tc->png_ptr)2940png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);2941png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc);2942png_bytep dp = png_voidcast(png_bytep, tc->dp);2943png_transform_gamma *tr =2944png_transform_cast(png_transform_gamma, *transform);2945const unsigned int bit_depth = tr->to_bit_depth;29462947affirm(tc->bit_depth == 16U && bit_depth < 8U);2948affirm(tr->shifts != 0U/*uninitialized*/);29492950/* This is exactly the same as above but without the gamma correction and2951* without the 8-bit target support. The code handles one or two channels,2952* but the result is not a PNG format unless the number of channels is just2953* 1 (grayscale).2954*2955* For multi-channel low bit depth the channels are packed into bytes using2956* the standard PNG big-endian packing.2957*/2958affirm((tc->format & PNG_FORMAT_FLAG_COLOR) == 0);2959/* The alpha shift is actually ignored; at present we only get here with an2960* alpha channel if it is to be removed for transparent alpha processing.2961*/2962debug(tc->format & PNG_FORMAT_FLAG_ALPHA ?2963(tr->shifts >> 8) == 1U : (tr->shifts >> 4) == 1U);2964debug(tc->transparent_alpha);29652966tc->sp = dp;2967/* This is a pure scaling operation so sBIT is not invalidated or altered. */2968tc->bit_depth = bit_depth;29692970/* TODO: maybe do this properly and use the alpha shift, but only the top bit2971* matters.2972*/2973{2974const unsigned int shift = tr->shifts & 0xFU;2975const png_uint_32 factor = tr->channel_scale[0];2976const png_uint_32 round = 1U << (31U-bit_depth);2977unsigned int bits = 8U;2978unsigned int ob = 0U;29792980do2981{2982png_uint_32 inb = *sp++ << 8; /* high bits first */2983inb += *sp++;29842985inb = ((inb >> shift) * factor + round) >> (32U-bit_depth);2986bits -= bit_depth;2987ob = ob | (inb << bits);2988if (bits == 0U)2989bits = 8U, *dp++ = PNG_BYTE(ob), ob = 0U;2990}2991while (sp < ep);29922993if (bits < 8U)2994*dp++ = PNG_BYTE(ob);2995}2996# undef png_ptr2997}29982999static void3000png_do_gamma8_down(png_transformp *transform, png_transform_controlp tc)3001{3002# define png_ptr (tc->png_ptr)3003png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);3004png_bytep dp = png_voidcast(png_bytep, tc->dp);3005png_const_bytep ep = dp + 1U/*safety*/;3006png_transform_gamma *tr =3007png_transform_cast(png_transform_gamma, *transform);3008const png_fixed_point correct = tr->correct;3009const png_uint_32 shifts = tr->shifts;30103011affirm(tc->bit_depth == 8U && tr->to_bit_depth == 16U);3012affirm(tr->shifts != 0U/*uninitialized*/);3013debug((shifts & 0x8888U) == 0U); /* all shifts 7 or less */3014debug(!tr->encode_alpha && !tr->optimize_alpha); /* only set for 16 bits */30153016sp += PNG_TC_ROWBYTES(*tc);3017tc->sp = dp;3018tc->bit_depth = tr->to_bit_depth;3019tc->gamma = tr->to_gamma;3020dp += PNG_TC_ROWBYTES(*tc);30213022{3023png_uint_32 alpha_scale;3024unsigned int channel, alpha;30253026debug((shifts >> (4*PNG_TC_CHANNELS(*tc))) == 1U);30273028/* We are going down so alpha, if present, is first. Notice that the init3029* routine has to reverse both 'shifts' and 'channel_scale' for the _down3030* cases.3031*/3032if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0)3033alpha_scale = alpha = 0U;30343035else3036{3037alpha = shifts;3038alpha_scale = tr->channel_scale[0U];3039}30403041channel = 1U;30423043do /* 8-bit --> 16-bit */3044{3045unsigned int inb = *--sp, shift;30463047if (channel == 1U)3048channel = shifts;30493050shift = channel & 0xFU;3051inb >>= shift;30523053if (channel == alpha) /* unencoded alpha, must scale */3054inb = (inb * alpha_scale + 0x8000U) >> 16;30553056else3057inb = png_gamma_nxmbit_correct(inb, correct, 8U-shift, 16U);30583059channel >>= 4;30603061*--dp = PNG_BYTE(inb);3062*--dp = PNG_BYTE(inb >> 8);3063}3064while (dp > ep);30653066debug(channel == 1U && dp == ep-1U);3067}3068# undef png_ptr3069}30703071static void3072png_do_expand8_down(png_transformp *transform, png_transform_controlp tc)3073{3074# define png_ptr (tc->png_ptr)3075png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);3076png_bytep dp = png_voidcast(png_bytep, tc->dp);3077png_const_bytep ep = dp + 1U/*safety*/;3078png_transform_gamma *tr =3079png_transform_cast(png_transform_gamma, *transform);3080const png_uint_32 shifts = tr->shifts;30813082affirm(tc->bit_depth == 8U && tr->to_bit_depth == 16U);3083affirm(tr->shifts != 0U/*uninitialized*/);30843085sp += PNG_TC_ROWBYTES(*tc);3086tc->sp = dp;3087tc->bit_depth = 16U;3088dp += PNG_TC_ROWBYTES(*tc);30893090{3091png_uint_32 channel = 1U;3092png_const_uint_32p scale = 0U;30933094do /* 8-bit -> 16-bit */3095{3096unsigned int inb = *--sp, shift;30973098if (channel == 1U)3099channel = shifts, scale = tr->channel_scale;31003101shift = channel & 0xFU;3102channel >>= 4;3103inb >>= shift;3104inb = (inb * *scale++ + 0x8000U) >> 16;3105/* dp starts beyond the end: */3106*--dp = PNG_BYTE(inb);3107*--dp = PNG_BYTE(inb >> 8);3108}3109while (dp > ep);31103111debug(channel == 1U && dp == ep-1U);3112}3113# undef png_ptr3114}31153116static void3117png_do_expand8_down_fast(png_transformp *transform, png_transform_controlp tc)3118/* Optimized version of the above for when the sBIT settings are all a full 83119* bits (the normal case).3120*/3121{3122# define png_ptr (tc->png_ptr)3123png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);3124png_bytep dp = png_voidcast(png_bytep, tc->dp);3125png_const_bytep ep = dp + 1U/*safety*/;3126png_transform_gamma *tr =3127png_transform_cast(png_transform_gamma, *transform);31283129affirm(tc->bit_depth == 8U && tr->to_bit_depth == 16U);3130affirm(tr->shifts != 0U/*uninitialized*/);31313132sp += PNG_TC_ROWBYTES(*tc);3133tc->sp = dp;3134tc->bit_depth = 16U;3135dp += PNG_TC_ROWBYTES(*tc);31363137do3138dp -= 2, dp[0] = dp[1] = *--sp;3139while (dp > ep);31403141debug(dp == ep-1U);3142# undef png_ptr3143}31443145static void3146png_init_gamma_uncached(png_transformp *transform, png_transform_controlp tc)3147{3148# define png_ptr (tc->png_ptr)3149png_transform_gamma *tr =3150png_transform_cast(png_transform_gamma, *transform);31513152debug(tc->init == PNG_TC_INIT_FINAL);31533154/* Set this first; the result says if the sBIT data is significant, but it is3155* ignored here.3156*/3157(void)init_gamma_sBIT(tr, tc);31583159/* If png_set_alpha_mode is called but no background processing needs to be3160* done (because there is no alpha channel or tRNS) we get to here with3161* potentially spurious alpha mode flags.3162*/3163if (!(tc->format & PNG_FORMAT_FLAG_ALPHA))3164tr->encode_alpha = tr->optimize_alpha = 0U;31653166/* Use separate functions for the two input depths but not for the five3167* possible output depths and four channel counts.3168*/3169if (tc->bit_depth == 8U)3170{3171if (tr->to_bit_depth <= 8U)3172tr->tr.fn = png_do_gamma8_up;31733174else3175{3176debug(tr->to_bit_depth == 16U);3177reverse_gamma_sBIT(tr);3178tr->tr.fn = png_do_gamma8_down;3179}3180}31813182else3183{3184affirm(tc->bit_depth == 16U);3185# ifdef PNG_READ_ALPHA_MODE_SUPPORTED3186if (!tr->optimize_alpha)3187tr->tr.fn = png_do_gamma16_up;3188else3189tr->tr.fn = png_do_gamma16_up_optimize;3190# else /* !READ_ALPHA_MODE */3191tr->tr.fn = png_do_gamma16_up;3192# endif /* !READ_ALPHA_MODE */3193}31943195/* Since the 'do' routines always perform gamma correction they will always3196* expand the significant bits to the full output bit depth.3197*/3198tc->invalid_info |= PNG_INFO_sBIT;3199tc->bit_depth = tr->to_bit_depth;3200tc->sBIT_R = tc->sBIT_G = tc->sBIT_B =3201png_check_byte(png_ptr, tc->bit_depth);3202if (tr->encode_alpha)3203tc->sBIT_A = tc->sBIT_G;3204tc->gamma = tr->to_gamma;3205# undef png_ptr3206}32073208#ifdef PNG_READ_sBIT_SUPPORTED3209static unsigned int3210tc_sBIT(png_const_transform_controlp tc)3211/* Determine the maximum number of significant bits in the row at this point.3212* This uses the png_struct::sig_bit field if it has not been invalidated,3213* otherwise it just returns the current bit depth.3214*/3215{3216const png_structrp png_ptr = tc->png_ptr;3217unsigned int bit_depth = tc->bit_depth;32183219if ((tc->invalid_info & PNG_INFO_sBIT) == 0U)3220{3221/* Normally the bit depth will not have been changed from the original PNG3222* depth, but it currently is changed by the grayscale expand to 8 bits,3223* an operation which doesn't invalidate sBIT.3224*/3225unsigned int sBIT;32263227if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0U)3228{3229/* Must use the largest of the sBIT depths, except that unset values3230* take priority.3231*/3232sBIT = png_ptr->sig_bit.red && png_ptr->sig_bit.green &&3233png_ptr->sig_bit.blue;32343235if (sBIT != 0U)3236{3237sBIT = png_ptr->sig_bit.red;32383239if (png_ptr->sig_bit.green > sBIT)3240sBIT = png_ptr->sig_bit.green;3241if (png_ptr->sig_bit.blue > sBIT)3242sBIT = png_ptr->sig_bit.blue;3243}3244}32453246else3247sBIT = png_ptr->sig_bit.gray;32483249if (sBIT > 0U && sBIT < bit_depth)3250bit_depth = sBIT;3251}32523253return bit_depth;3254}3255#else /* !READ_sBIT */3256# define tc_sBIT(tc) ((tc)->bit_depth)3257#endif /* READ_sBIT */32583259static void3260png_init_gamma(png_transformp *transform, png_transform_controlp tc)3261{3262const png_structrp png_ptr = tc->png_ptr;3263png_transform_gamma *tr =3264png_transform_cast(png_transform_gamma, *transform);32653266if (tc->init == PNG_TC_INIT_FORMAT)3267{3268/* This should only happen for the final encode gamma transform, which3269* never initializes the target bit depth (see png_set_gamma and3270* png_set_alpha_mode). The affirm is required here; in we can't continue3271* safely if the bit depth has been set somehow.3272*/3273debug(tr->tr.order == PNG_TR_GAMMA_ENCODE);3274affirm(tr->to_gamma > 0 && tr->to_bit_depth == 0U);32753276/* At this point the output gamma should not have been set yet: */3277debug(png_ptr->row_gamma == 0);32783279/* The following must be true; png_set_gamma and png_set_alpha_mode set3280* (or default) the PNG gamma and other routines that insert a gamma3281* transform must only do in PNG_TC_INIT_FINAL:3282*/3283debug(tc->gamma > 0);32843285/* At this point the data gamma must be updated so that we get the correct3286* png_struct::row_gamma at the end of the init:3287*/3288tc->gamma = tr->to_gamma;32893290/* For safety invalidate the sBIT information too; we don't know yet3291* whether a gamma transform will be required but if it is the sBIT3292* information becomes invalid.3293*/3294tc->invalid_info |= PNG_INFO_sBIT;3295}32963297else /* PNG_TC_INIT_FINAL */3298{3299/* It is very bad if we get here when processing a row: */3300affirm(tc->init == PNG_TC_INIT_FINAL && png_ptr->row_bit_depth > 0);33013302/* There are three cases:3303*3304* 1) Gamma correction is required, output bit depth may need to be3305* defaulted.3306* 2) Gamma correction is not required but a bit depth change is3307* necessary.3308* 3) Neither is required; the transform can be eliminated.3309*3310* First default the bit depth if it is not already set. Note that if the3311* output is a palette then 'row_bit_depth' refers to the palette size and3312* 8U must be used here. tc->palette is irrelevant; it only tells us that3313* the data came from a palette.3314*/3315if (tr->to_bit_depth == 0)3316{3317if ((png_ptr->row_format & PNG_FORMAT_FLAG_COLORMAP) != 0U)3318tr->to_bit_depth = 8U;33193320else3321tr->to_bit_depth = png_ptr->row_bit_depth;3322}33233324/* (1); is gamma correction required? If tc->gamma is 0 at this point it3325* is not, but then the png_struct::row_gamma should be 0 too.3326*/3327implies(tc->gamma == 0, png_ptr->row_gamma == 0);3328implies(tr->to_gamma == 0, tc->gamma == 0);33293330if (!png_gamma_equal(png_ptr, tc->gamma, tr->to_gamma, &tr->correct,3331tc_sBIT(tc)))3332{3333/* First make sure the input doesn't have a tRNS chunk which needs to3334* be expanded now; if it does push_gamma_expand will push an3335* appropriate transform *before* this one and we need to return3336* immediately (the caller will call back to this function).3337*/3338if (push_gamma_expand(transform, tc, 0/*need alpha*/))3339{3340affirm(tc->bit_depth >= 8U &&3341(tc->invalid_info & PNG_INFO_tRNS) != 0U &&3342*transform != &tr->tr);3343return;3344}33453346debug(*transform == &tr->tr && tc->bit_depth >= 8U);33473348/* The format is now 8 or 16-bit G, GA, RGB or RGBA and gamma3349* correction is required.3350*/3351png_init_gamma_uncached(transform, tc);3352/* TODO: implement caching for the !tc->caching cases! */3353return;3354}33553356/* The cases where the two gamma values are close enough to be considered3357* equal. The code lies about the gamma; this prevents apps and the3358* simplified API getting into loops or bad conditions because the gamma3359* was not set to the expected value.3360*3361* Note that png_transform_control::gamma is only set here if both the3362* input and output gamma values are known, otherwise the transform3363* introduces a spurious know gamma value.3364*/3365if (tr->to_gamma > 0 && tc->gamma > 0)3366tc->gamma = tr->to_gamma;33673368if (tr->to_bit_depth > tc->bit_depth)3369{3370/* This is either the to-linear operation, in which case the expected3371* bit depth is 16U, or it is the final encode in the case where an3372* 'expand' operation was also specified.3373*3374* We don't care about the PNG_TR_GAMMA_ENCODE case because we know3375* that there has to be an expand operation further down the pipeline.3376*/3377if (tr->tr.order < PNG_TR_GAMMA_ENCODE)3378{3379affirm(tr->to_bit_depth == 16U);33803381if (push_gamma_expand(transform, tc, 0/*need alpha*/))3382{3383affirm(tc->bit_depth == 8U &&3384(tc->invalid_info & PNG_INFO_tRNS) != 0U &&3385*transform != &tr->tr);3386return;3387}33883389debug(*transform == &tr->tr);3390affirm(tc->bit_depth == 8U); /* if 16U we would not be here! */33913392/* not using byte_ops here, but if there is no sBIT required3393* (normally the case) the fast code can be used:3394*/3395if (init_gamma_sBIT(tr, tc))3396tr->tr.fn = png_do_expand8_down;33973398else3399tr->tr.fn = png_do_expand8_down_fast;34003401tc->bit_depth = 16U;3402}34033404else /* PNG_TR_GAMMA_ENCODE: nothing need be done */3405tr->tr.fn = NULL;3406}34073408else if (tr->to_bit_depth < tc->bit_depth)3409{3410/* No gamma correction but bit depth *reduction* is required. Expect3411* the 'from' bit depth to always be 16, otherwise this transform3412* should not have been pushed. Also expect this to be the gamma3413* 'encode' operation at the end of the arithmetic.3414*/3415affirm(tc->bit_depth == 16U && tr->tr.order == PNG_TR_GAMMA_ENCODE);34163417/* If the target bit depth is 8-bit delay the operation and use the3418* standard 16-8-bit scale code. For low bit depth do it now.3419*/3420if (tr->to_bit_depth == 8U)3421{3422png_set_scale_16(png_ptr);3423tr->tr.fn = NULL;3424}34253426else /* low bit depth */3427{3428(void)init_gamma_sBIT(tr, tc);3429tr->tr.fn = png_do_scale16_up;3430tc->bit_depth = tr->to_bit_depth;3431}3432}34333434else /* gamma !significant and nothing to do */3435tr->tr.fn = NULL;3436}3437}34383439#if !PNG_RELEASE_BUILD3440int /* PRIVATE(debug only) */3441png_gamma_check(png_const_structrp png_ptr, png_const_transform_controlp tc)3442/* Debugging only routine to repeat the test used above to determine if the3443* gamma was insignificant.3444*3445* NOTE: JB20160723: This may still be incorrect in a complicated transform3446* pipeline because it uses 'tc_sBIT' for the end of the pipeline whereas the3447* init above happens earlier. I don't think this matters because the test3448* is only invoked if the gamma transform is eliminated or if there is a bug3449* and in the former case the sBIT values should remain unchanged.3450*/3451{3452png_fixed_point dummy;34533454return png_gamma_equal(png_ptr, png_ptr->row_gamma, tc->gamma, &dummy,3455tc_sBIT(tc));3456}3457#endif /* !RELEASE_BUILD */34583459static png_fixed_point3460translate_gamma_flags(png_const_structrp png_ptr, png_fixed_point gamma,3461int is_screen)3462/* If 'is_screen' is set this returns the inverse of the supplied value; i.e.3463* this routine always returns an encoding value.3464*/3465{3466/* Check for flag values. The main reason for having the old Mac value as a3467* flag is that it is pretty near impossible to work out what the correct3468* value is from Apple documentation - a working Mac system is needed to3469* discover the value!3470*/3471switch (gamma)3472{3473case PNG_DEFAULT_sRGB:3474case PNG_GAMMA_sRGB:3475case PNG_FP_1/PNG_GAMMA_sRGB: /* stupid case: -100000 */3476gamma = PNG_GAMMA_sRGB_INVERSE;3477break;34783479case PNG_GAMMA_MAC_18:3480case PNG_FP_1/PNG_GAMMA_MAC_18: /* stupid case: -50000 */3481gamma = PNG_GAMMA_MAC_INVERSE;3482break;34833484default:3485if (is_screen)3486{3487/* Check for a ridiculously low value; this will result in an3488* overflow3489* in the reciprocal calculation.3490*/3491if (gamma < 5)3492{3493png_app_error(png_ptr, "invalid screen gamma (too low)");3494gamma = 0;3495}34963497else if (gamma != PNG_FP_1) /* optimize linear */3498gamma = png_reciprocal(gamma);3499}35003501else if (gamma <= 0)3502{3503png_app_error(png_ptr, "invalid file gamma (too low)");3504gamma = 0;3505}3506break;3507}35083509return gamma;3510}35113512static png_transform_gamma *3513add_gamma_transform(png_structrp png_ptr, unsigned int order,3514png_fixed_point gamma, unsigned int bit_depth, int force)3515{3516/* Add a png_transform_gamma transform at the given position; this is a3517* utility which just adds the transform and (unconditionally) overwrites the3518* to_gamma field. gamma must be valid. If 'force' is true the gamma value3519* in an existing transform will be overwritten, otherwise this is just a3520* default value.3521*/3522png_transform_gamma *tr = png_transform_cast(png_transform_gamma,3523png_add_transform(png_ptr, sizeof (png_transform_gamma), png_init_gamma,3524order));35253526if (force || tr->to_gamma == 0)3527tr->to_gamma = gamma;35283529tr->to_bit_depth = bit_depth;35303531return tr;3532}35333534void PNGFAPI3535png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,3536png_fixed_point file_gamma)3537{3538png_debug(1, "in png_set_gamma_fixed");35393540/* Validate the passed in file gamma value: */3541file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);35423543/* The returned value may be 0, this results in a png_app_error above which3544* may be ignored; if that happens simply ignore the setting.3545*/3546if (file_gamma > 0)3547{3548/* Set the colorspace gamma value unconditionally - this overrides the3549* value in the PNG file if a gAMA chunk was present. png_set_alpha_mode3550* provides a different, easier, way to default the file gamma.3551*/3552png_ptr->colorspace.gamma = file_gamma;3553if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)3554png_ptr->colorspace.flags = PNG_COLORSPACE_HAVE_GAMMA;3555else3556png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;3557}35583559/* Do the same thing with the screen gamma; check it and handle it if valid.3560* This adds/sets the encoding of the final gamma transform in the chain.3561* png_set_alpha_mode does the same thing.3562*/3563scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);35643565if (scrn_gamma > 0)3566(void)add_gamma_transform(png_ptr, PNG_TR_GAMMA_ENCODE, scrn_gamma,35670/*bit depth*/, 1/*force to_gamma to scrn_gamma*/);3568}35693570#ifdef PNG_FLOATING_POINT_SUPPORTED3571static png_fixed_point3572convert_gamma_value(png_structrp png_ptr, double output_gamma)3573{3574/* The following silently ignores cases where fixed point (times 100,000)3575* gamma values are passed to the floating point API. This is safe and it3576* means the fixed point constants work just fine with the floating point3577* API. The alternative would just lead to undetected errors and spurious3578* bug reports. Negative values fail inside the _fixed API unless they3579* correspond to the flag values.3580*/3581if (output_gamma < 0 || output_gamma > 128)3582output_gamma *= .00001;35833584return png_fixed(png_ptr, output_gamma, "gamma value");3585}35863587void PNGAPI3588png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)3589{3590png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),3591convert_gamma_value(png_ptr, file_gamma));3592}3593#endif /* FLOATING_POINT */3594#endif /* READ_GAMMA */35953596#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED3597static void3598png_do_rtog_48(png_transformp *transform, png_transform_controlp tc)3599{3600# define png_ptr (tc->png_ptr)3601const png_uint_32 r = (*transform)->args >> 16;3602const png_uint_32 g = (*transform)->args & 0xFFFFU;3603const png_uint_32 b = 65536U - r - g;36043605png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);3606const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 6U;3607png_bytep dp = png_voidcast(png_bytep, tc->dp);36083609debug(tc->bit_depth == 16U && tc->format == PNG_FORMAT_FLAG_COLOR &&3610(tc->gamma == 0U || !png_gamma_significant(png_ptr, tc->gamma, 16U)));36113612tc->sp = dp;3613tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR);36143615while (sp <= ep)3616{3617png_uint_32 gray = (((sp[0] << 8) + sp[1]) * r +3618((sp[2] << 8) + sp[3]) * g +3619((sp[4] << 8) + sp[5]) * b + 32767U) >> 16;36203621debug(gray < 65536U);3622*dp++ = PNG_BYTE(gray >> 8);3623*dp++ = PNG_BYTE(gray);3624sp += 6U;3625}3626# undef png_ptr3627}36283629static void3630png_do_rtog_64(png_transformp *transform, png_transform_controlp tc)3631{3632# define png_ptr (tc->png_ptr)3633const png_uint_32 r = (*transform)->args >> 16;3634const png_uint_32 g = (*transform)->args & 0xFFFFU;3635const png_uint_32 b = 65536U - r - g;36363637png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);3638const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 8U;3639png_bytep dp = png_voidcast(png_bytep, tc->dp);36403641debug(tc->bit_depth == 16U &&3642tc->format == PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA &&3643(tc->gamma == 0U || !png_gamma_significant(png_ptr, tc->gamma, 16U)));36443645tc->sp = dp;3646tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR);36473648while (sp <= ep)3649{3650png_uint_32 gray = (((sp[0] << 8) + sp[1]) * r +3651((sp[2] << 8) + sp[3]) * g +3652((sp[4] << 8) + sp[5]) * b + 32767U) >> 16;36533654debug(gray < 65536U);3655*dp++ = PNG_BYTE(gray >> 8);3656*dp++ = PNG_BYTE(gray);3657sp += 6U;3658*dp++ = *sp++; /* alpha */3659*dp++ = *sp++;3660}3661# undef png_ptr3662}36633664static void3665png_init_rgb_to_gray_arithmetic(png_transformp *transform,3666png_transform_controlp tc)3667{3668# define png_ptr (tc->png_ptr)3669/* This only gets used in the final init stage: */3670debug(tc->init == PNG_TC_INIT_FINAL && tc->bit_depth == 16U &&3671(tc->format & PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA)) ==3672PNG_FORMAT_FLAG_COLOR);36733674(*transform)->fn = (tc->format & PNG_FORMAT_FLAG_ALPHA) ? png_do_rtog_64 :3675png_do_rtog_48;36763677tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR);3678tc->invalid_info |= PNG_INFO_sBIT;3679tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A =3680png_check_byte(png_ptr, tc->bit_depth);3681# undef png_ptr3682}36833684typedef struct3685{3686png_transform tr;3687png_fixed_point red_coefficient;3688png_fixed_point green_coefficient;3689unsigned int coefficients_set :1;3690unsigned int error_action :2;3691} png_transform_rgb_to_gray;36923693static void3694png_update_rgb_status(png_structrp png_ptr, png_transformp *transform)3695{3696png_transform_rgb_to_gray *tr = png_transform_cast(png_transform_rgb_to_gray,3697*transform);36983699png_ptr->rgb_to_gray_status = 1U;3700tr->tr.fn = NULL; /* one warning/error only */37013702switch (tr->error_action)3703{3704case PNG_ERROR_ACTION_WARN:3705png_warning(png_ptr, "RGB to gray found nongray pixel");3706break;37073708case PNG_ERROR_ACTION_ERROR:3709png_error(png_ptr, "RGB to gray found nongray pixel");3710break;37113712default:3713break;3714}3715}37163717static void3718png_do_rgb_check24(png_transformp *transform, png_transform_controlp tc)3719{3720# define png_ptr (tc->png_ptr)3721/* Sets 'rgb_to_gray' status if a pixel is found where the red green and blue3722* channels are not equal.3723*/3724png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);3725const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 3U;37263727debug(tc->bit_depth == 8U && tc->format == PNG_FORMAT_FLAG_COLOR);37283729while (sp <= ep)3730{3731if ((sp[0] ^ sp[1]) | (sp[2] ^ sp[1]))3732{3733png_update_rgb_status(png_ptr, transform);3734break;3735}37363737sp += 3U;3738}3739# undef png_ptr3740}37413742static void3743png_do_rgb_check32(png_transformp *transform, png_transform_controlp tc)3744{3745# define png_ptr (tc->png_ptr)3746/* Sets 'rgb_to_gray' status if a pixel is found where the red green and blue3747* channels are not equal and alpha is not zero.3748*/3749png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);3750const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 4U;37513752debug(tc->bit_depth == 8U &&3753tc->format == PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA);37543755while (sp <= ep)3756{3757if (((sp[0] ^ sp[1]) | (sp[2] ^ sp[1])) && sp[3] != 0)3758{3759png_update_rgb_status(png_ptr, transform);3760break;3761}37623763sp += 4U;3764}3765# undef png_ptr3766}37673768static void3769png_do_rgb_check48(png_transformp *transform, png_transform_controlp tc)3770{3771# define png_ptr (tc->png_ptr)3772/* Sets 'rgb_to_gray' status if a pixel is found where the red green and blue3773* channels are not equal.3774*/3775png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);3776const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 6U;37773778debug(tc->bit_depth == 16U && tc->format == PNG_FORMAT_FLAG_COLOR);37793780while (sp <= ep)3781{3782if ((sp[0] ^ sp[2]) | (sp[4] ^ sp[2]) |3783(sp[1] ^ sp[3]) | (sp[5] ^ sp[3]))3784{3785png_update_rgb_status(png_ptr, transform);3786break;3787}37883789sp += 6U;3790}3791# undef png_ptr3792}37933794static void3795png_do_rgb_check64(png_transformp *transform, png_transform_controlp tc)3796{3797# define png_ptr (tc->png_ptr)3798/* Sets 'rgb_to_gray' status if a pixel is found where the red green and blue3799* channels are not equal and alpha is not zero.3800*/3801png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);3802const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 8U;38033804debug(tc->bit_depth == 16U &&3805tc->format == PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA);38063807while (sp <= ep)3808{3809if (((sp[0] ^ sp[2]) | (sp[4] ^ sp[2]) |3810(sp[1] ^ sp[3]) | (sp[5] ^ sp[3])) &&3811(sp[6] | sp[7]) != 0)3812{3813png_update_rgb_status(png_ptr, transform);3814break;3815}38163817sp += 8U;3818}3819# undef png_ptr3820}38213822static void3823png_init_rgb_to_gray(png_transformp *transform, png_transform_controlp tc)3824{3825png_structrp png_ptr = tc->png_ptr;38263827/* Basic checks: if there is no color in the format this transform is not3828* applicable.3829*/3830if ((tc->format & PNG_FORMAT_FLAG_COLOR) != 0)3831{3832png_transform_rgb_to_gray *tr = png_transform_cast(3833png_transform_rgb_to_gray, *transform);38343835/* no colormap allowed: */3836affirm(tc->init && !(tc->format & PNG_FORMAT_FLAG_COLORMAP));3837/* no extra flags yet: */3838debug(!(tc->format &3839PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA)));3840/* at present no non-palette caching: */3841implies(tc->caching, tc->palette);38423843if (tc->init == PNG_TC_INIT_FORMAT)3844{3845/* The convertion should just remove the 'COLOR' flag and do nothing3846* else, but if a tRNS chunk is present this would invalidate it.3847* Handle this by expanding it now.3848*/3849if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0 && !tc->palette &&3850png_ptr->num_trans == 1 && !(tc->invalid_info & PNG_INFO_tRNS))3851{3852/* Only if expand was requested and not cancelled: */3853if (tc->expand_tRNS && !tc->strip_alpha)3854tc->format |= PNG_FORMAT_FLAG_ALPHA;38553856tc->invalid_info |= PNG_INFO_tRNS; /* prevent expansion later */3857}38583859tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR);3860}38613862else /* PNG_TC_INIT_FINAL */3863{3864unsigned int index; /* channel to select (invalid) */3865png_byte sBIT_color; /* sBIT of that channel if valid */3866png_fixed_point r, g; /* Coefficients in range 0..65536 */38673868/* Push a tRNS transform if required. Because this is a push the3869* transform the init needs to be run now. This needs to go in3870* before the check on r==g==b because a color key might be used.3871*/3872if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0 && !tc->palette &&3873png_ptr->num_trans == 1 && !(tc->invalid_info & PNG_INFO_tRNS))3874{3875if (tc->expand_tRNS && !tc->strip_alpha)3876{3877png_transformp tr_expand = png_push_transform(png_ptr,3878sizeof (png_expand), png_init_expand, transform, NULL);38793880debug(*transform == tr_expand);3881tr_expand->args |= PNG_EXPAND_tRNS;3882png_init_expand(transform, tc);3883/* Check for the infinite loop possibility: */3884affirm((tc->invalid_info & PNG_INFO_tRNS) != 0);3885return;3886}38873888else3889tc->invalid_info |= PNG_INFO_tRNS;3890}38913892{3893png_fixed_point red, green;38943895if (tr->coefficients_set)3896{3897red = tr->red_coefficient;3898green = tr->green_coefficient;3899}39003901# ifdef PNG_COLORSPACE_SUPPORTED3902else if ((png_ptr->colorspace.flags &3903(PNG_COLORSPACE_HAVE_ENDPOINTS+PNG_COLORSPACE_INVALID))3904== PNG_COLORSPACE_HAVE_ENDPOINTS)3905{3906red = png_ptr->colorspace.end_points_XYZ.red_Y;3907green = png_ptr->colorspace.end_points_XYZ.green_Y;3908}3909# endif39103911else /* no colorspace support, assume sRGB */3912{3913/* From IEC 61966-2-1:1999, the reverse transformation from sRGB3914* RGB values to XYZ D65 values (not CIEXYZ!). These are not3915* exact inverses of the forward transformation; they only have3916* four (decimal) digits of precision.3917*3918* API CHANGE: in 1.7.0 the sRGB values from the official IEC3919* specification are used, previously libpng used values from3920* Charles Poynton's ColorFAQ of 1998-01-04. The original page3921* is gone, however up to date information can be found below:3922*3923* http://www.poynton.com/ColorFAQ.html3924*3925* At the time of reading (20150628) this web site quotes the3926* same values as below and cites ITU Rec 709 as the source.3927*/3928red = 21260;3929green = 71520;3930}39313932/* Prior to 1.7 this calculation was done with 15-bit precision,3933* this is because the code was written pre-muldiv and tried to3934* work round the problems caused by the signs in integer3935* calculations.3936*/3937(void)png_muldiv(&r, red, 65536, PNG_FP_1);3938(void)png_muldiv(&g, green, 65536, PNG_FP_1);3939}39403941/* If the convertion can be deduced to select a single channel do so.3942* If the error action is set to error just copy the red channel, if3943* the coefficients select just one channel use that.3944*/3945if (tr->error_action == PNG_ERROR_ACTION_ERROR || r >= 65536)3946index = 0U, sBIT_color = tc->sBIT_R; /* select red */39473948else if (g >= 65536)3949index = 1U, sBIT_color = tc->sBIT_G; /* select green */39503951else if (r + g == 0)3952index = 2U, sBIT_color = tc->sBIT_B; /* select blue */39533954else3955index = 3U, sBIT_color = 0U/*UNUSED*/;39563957if (index == 3U)3958{3959/* Arithmetic will have to be done. For this we need linear 16-bit3960* data which must then be converted back to the required bit depth,3961* png_init_gamma handles this. It may push other expand operations3962* (it shouldn't but it can), so give it some space.3963*3964* The gamma must be restored to the original value, 0U for the bit3965* depth means use the output bit depth.3966*/3967(void)add_gamma_transform(png_ptr, PNG_TR_GAMMA_ENCODE, tc->gamma,39680U/*bit depth*/, 0/*default*/);39693970/* If png_init_gamma is called with tc->gamma 0 it does the right3971* thing in PNG_TC_INIT_FINAL; it just does any required bit depth3972* adjustment.3973*/3974(void)add_gamma_transform(png_ptr, tr->tr.order + 0x10U, PNG_FP_1,397516U, 1/*force: doesn't matter*/);39763977{3978/* This init routine will update the sBIT information3979* appropriately.3980*/3981png_transformp tr_rtog = png_add_transform(png_ptr, 0/*size*/,3982png_init_rgb_to_gray_arithmetic, tr->tr.order + 0x20U);39833984/* r and g are known to be in the range 0..65535, so pack them3985* into the 'args' argument of a new transform.3986*/3987tr_rtog->args = (((png_uint_32)r) << 16) + g;3988}3989}39903991else /* index < 3 */3992{3993/* TODO: does this need to select the correct sBIT value too? */3994png_add_rgb_to_gray_byte_ops(png_ptr, tc, index,3995tr->tr.order + 0x10U);3996tc->sBIT_G = sBIT_color;3997}39983999/* Prior to 1.7 libpng would always check for r!=g!=b. In 1.7 an extra4000* error_action setting is added to prevent this overhead.4001*/4002if (tr->error_action)4003tr->tr.fn = tc->bit_depth == 8 ?4004((tc->format & PNG_FORMAT_FLAG_ALPHA) ?4005png_do_rgb_check32 : png_do_rgb_check24) :4006((tc->format & PNG_FORMAT_FLAG_ALPHA) ?4007png_do_rgb_check64 : png_do_rgb_check48);40084009else4010tr->tr.fn = NULL; /* PNG_ERROR_ACTION_NO_CHECK */4011}4012}40134014else /* not color: transform not applicable */4015(*transform)->fn = NULL;4016}40174018void PNGFAPI4019png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,4020png_fixed_point red, png_fixed_point green)4021/* API CHANGE: in 1.7 calling this on a palette PNG no longer causes the4022* palette to be expanded (unless explicitly requested), rather it converts4023* the palette to grayscale.4024*/4025{4026/* The coefficients must be reasonable, the error handling is to warn (pre4027* 1.7) or app error (1.7) and drop back to the cHRM definition of Y. The4028* drop back is done in the init routine if relevant flag is unset. Passing4029* negative values causes this default to be used without a warning.4030*/4031int pset = 0;40324033if (red >= 0 && green >= 0)4034{4035if (red <= PNG_FP_1 && green <= PNG_FP_1 && red + green <= PNG_FP_1)4036pset = 1;40374038else /* overflow */4039png_app_error(png_ptr, "rgb_to_gray coefficients too large (ignored)");4040}40414042{4043png_transform_rgb_to_gray *tr =4044png_transform_cast(png_transform_rgb_to_gray,4045png_add_transform(png_ptr, sizeof (png_transform_rgb_to_gray),4046png_init_rgb_to_gray, PNG_TR_RGB_TO_GRAY));40474048tr->error_action = 0x3U & error_action;40494050if (red < 0 || green < 0) /* use cHRM default */4051tr->coefficients_set = 0U;40524053else if (pset) /* else bad coefficients which get ignored */4054{4055tr->coefficients_set = 1U;4056tr->red_coefficient = red;4057tr->green_coefficient = green;4058}4059}4060}40614062#ifdef PNG_FLOATING_POINT_SUPPORTED4063/* Convert a RGB image to a grayscale of the same width. This allows us,4064* for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.4065*/40664067void PNGAPI4068png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,4069double green)4070{4071png_set_rgb_to_gray_fixed(png_ptr, error_action,4072png_fixed(png_ptr, red, "rgb to gray red coefficient"),4073png_fixed(png_ptr, green, "rgb to gray green coefficient"));4074}4075#endif /* FLOATING POINT */4076#endif /* RGB_TO_GRAY */40774078#ifdef PNG_READ_BACKGROUND_SUPPORTED4079typedef struct4080{4081png_transform tr;4082struct4083{4084png_color_16 background;4085unsigned int need_expand :1; /* Background matches format of PNG */4086unsigned int rgb_to_gray :1; /* RGB-to-gray transform found */4087unsigned int compose_background :1; /* png_set_background */4088unsigned int associate_alpha :1;4089unsigned int encode_alpha :1;4090unsigned int optimize_alpha :1;4091unsigned int background_is_gray :1; /* Background color is gray */4092unsigned int background_bit_depth :5; /* bit depth, 1..16 */4093unsigned int ntrans :3; /* 1..6 bytes */4094png_byte transparent_pixel[6];4095png_byte background_pixel[6];4096png_fixed_point background_gamma;4097} st; /* to allow the whole state to be copied reliably */4098} png_transform_background;40994100static void4101resolve_background_color(png_transform_background *tr,4102png_transform_controlp tc)4103{4104png_const_structp png_ptr = tc->png_ptr;41054106/* Deduce the bit depth and color information for the background, the4107* special case is when need_expand is set and the PNG has palette format,4108* then (and only then) the background value is a palette index.4109*/4110if (tr->st.need_expand && tc->palette)4111{4112unsigned int i = tr->st.background.index;4113png_byte r, g, b;41144115if (i >= png_ptr->num_palette)4116{4117png_app_error(png_ptr, "background index out of range");4118tr->tr.fn = NULL;4119return;4120}41214122tr->st.background_bit_depth = 8U;4123r = png_ptr->palette[i].red;4124g = png_ptr->palette[i].green;4125b = png_ptr->palette[i].blue;41264127if (r == g && g == b)4128{4129tr->st.background_is_gray = 1U;4130tr->st.background.gray = g;4131UNTESTED4132}41334134else4135{4136tr->st.background_is_gray = 0U;4137tr->st.background.red = r;4138tr->st.background.green = g;4139tr->st.background.blue = b;4140UNTESTED4141}4142}41434144else /* background is not a palette index */4145{4146int use_rgb;4147png_uint_16 mask;41484149/* First work out the bit depth and whether or not to use the RGB4150* fields of the background.4151*/4152if (tr->st.need_expand)4153{4154affirm(!(tc->format & PNG_FORMAT_FLAG_COLORMAP));4155tr->st.background_bit_depth =4156png_check_bits(png_ptr, png_ptr->bit_depth, 5U);4157use_rgb = (png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0;4158}41594160else /* screen format background */4161{4162/* If the final output is in palette format assume the background4163* is in a matching format. This covers two cases, an original4164* COLORMAP PNG and png_set_quantize.4165*/4166if ((png_ptr->row_format & PNG_FORMAT_FLAG_COLORMAP) != 0)4167tr->st.background_bit_depth = 8U;41684169else4170tr->st.background_bit_depth =4171png_check_bits(png_ptr, png_ptr->row_bit_depth, 5U);41724173use_rgb = (png_ptr->row_format & PNG_FORMAT_FLAG_COLOR) != 0;4174}41754176/* The PNG spec says to use the low bits of the values, so we mask out4177* the high bits here (at present no warning is produced if they are4178* set.)4179*/4180mask = png_check_u16(png_ptr, (1U << tr->st.background_bit_depth)-1U);41814182if (use_rgb)4183{4184png_uint_16 r, g, b;41854186r = tr->st.background.red & mask;4187g = tr->st.background.green & mask;4188b = tr->st.background.blue & mask;41894190if (r == g && g == b)4191{4192tr->st.background_is_gray = 1U;4193tr->st.background.gray = g;4194}41954196else4197{4198tr->st.background_is_gray = 0U;4199tr->st.background.red = r;4200tr->st.background.green = g;4201tr->st.background.blue = b;4202}4203}42044205else /* gray */4206{4207tr->st.background_is_gray = 1U;4208tr->st.background.gray = tr->st.background.gray & mask;4209}4210}4211}42124213static void4214gamma_correct_background_component(png_const_structrp png_ptr, png_uint_16p cp,4215unsigned int bdc, png_fixed_point correction, unsigned int bdout)4216/* Utility function for gamma_correct_background. */4217{4218unsigned int c = *cp;42194220/* 0.0 and 1.0 are unchanged (and common): */4221if (c > 0U && c < (1U<<bdc)-1U)4222{4223if (correction != 0)4224c = png_check_bits(png_ptr,4225png_gamma_nxmbit_correct(c, correction, bdc, bdout), bdout);42264227else if (bdc != bdout)4228{4229/* Scale the value from bdc to bdout bits. */4230png_int_32 i;4231affirm(png_muldiv(&i, c, (1U<<bdout)-1U, (1U<<bdc)-1U));4232c = png_check_bits(png_ptr, i, bdout);4233}4234}42354236else if (c != 0U)4237c = (1U << bdout) - 1U;42384239*cp = PNG_UINT_16(c);4240PNG_UNUSED(png_ptr) /* if checking disabled */4241}42424243static void4244gamma_correct_background(png_transform_background *tr,4245png_const_transform_controlp tc)4246{4247# define png_ptr (tc->png_ptr)4248png_fixed_point correction = tc->gamma;4249const unsigned int bdback = tr->st.background_bit_depth;4250const unsigned int bdrow = tc->bit_depth;42514252/* This is harmless if it fails but it will damage the output pixels - they4253* won't have the requested color depth accuracy where the background is4254* used.4255*/4256debug(bdback <= bdrow);4257debug(tr->st.background_is_gray || (bdrow >= 8U && bdback >= 8U));42584259/* The background is assumed to be full precision; there is no sBIT4260* information for it. The convertion converts from the current depth and4261* gamma of the background to that in the transform control. It uses the4262* full 16-bit precision when considering the gamma values even though this4263* is probably spurious.4264*/4265if (correction != 0 && (tr->st.background_gamma == 0 ||4266png_gamma_equal(png_ptr, tr->st.background_gamma, correction,4267&correction, 16U)))4268correction = 0; /* no correction! */42694270if (tr->st.background_is_gray)4271gamma_correct_background_component(png_ptr, &tr->st.background.gray,4272bdback, correction, bdrow);42734274else4275{4276gamma_correct_background_component(png_ptr, &tr->st.background.red,4277bdback, correction, bdrow);4278gamma_correct_background_component(png_ptr, &tr->st.background.green,4279bdback, correction, bdrow);4280gamma_correct_background_component(png_ptr, &tr->st.background.blue,4281bdback, correction, bdrow);4282}42834284/* Regardless of whether there was a correction set the background gamma: */4285tr->st.background_gamma = tc->gamma;4286tr->st.background_bit_depth = png_check_bits(png_ptr, bdrow, 5U);4287# undef png_ptr4288}42894290static void4291fill_background_pixel(png_transform_background *tr, png_transform_controlp tc)4292{4293# define png_ptr (tc->png_ptr)4294/* Fill in 'background_pixel' if the appropriate sequence of bytes for the4295* format given in the transform control.4296*/4297unsigned int bdtc = tc->bit_depth;42984299/* If necessary adjust the background pixel to the current row format (it is4300* important to do this as late as possible to avoid spurious4301* interconvertions).4302*/4303gamma_correct_background(tr, tc);43044305if (tr->st.background_is_gray)4306{4307unsigned int g = tr->st.background.gray;43084309/* 'g' now has enough bits for the destination, note that in the case of4310* low bit depth gray this causes the pixel to be replicated through the4311* written byte. Fill all six bytes with the replicated background:4312*/4313while (bdtc < 8U)4314{4315g &= (1U << bdtc) - 1U; /* use only the low bits */4316g |= g << bdtc;4317bdtc <<= 1;4318}43194320memset(tr->st.background_pixel, PNG_BYTE(g), 6U);4321if (bdtc == 16U)4322tr->st.background_pixel[0] = tr->st.background_pixel[2] =4323tr->st.background_pixel[4] = PNG_BYTE(g >> 8);4324/* Must not include the alpha channel here: */4325tr->st.ntrans = png_check_bits(png_ptr,4326((tc->format & PNG_FORMAT_FLAG_COLOR)+1U) << (bdtc == 16U), 3U);4327}43284329else4330{4331unsigned int r = tr->st.background.red;4332unsigned int g = tr->st.background.green;4333unsigned int b = tr->st.background.blue;43344335debug((tc->format & PNG_FORMAT_FLAG_COLOR) != 0);43364337switch (bdtc)4338{4339case 8U:4340tr->st.background_pixel[0] = PNG_BYTE(r);4341tr->st.background_pixel[1] = PNG_BYTE(g);4342tr->st.background_pixel[2] = PNG_BYTE(b);4343tr->st.ntrans = 3U;4344break;43454346case 16U:4347tr->st.background_pixel[0] = PNG_BYTE(r>>8);4348tr->st.background_pixel[1] = PNG_BYTE(r);4349tr->st.background_pixel[2] = PNG_BYTE(g>>8);4350tr->st.background_pixel[3] = PNG_BYTE(g);4351tr->st.background_pixel[4] = PNG_BYTE(b>>8);4352tr->st.background_pixel[5] = PNG_BYTE(b);4353tr->st.ntrans = 6U;4354break;43554356default:4357NOT_REACHED;4358}4359}4360# undef png_ptr4361}43624363/* Look for colors matching the trans_color in png_ptr and replace them. This4364* must handle all the non-alpha formats.4365*/4366static void4367png_do_replace_tRNS_multi(png_transformp *transform, png_transform_controlp tc)4368{4369# define png_ptr (tc->png_ptr)4370png_transform_background *tr =4371png_transform_cast(png_transform_background, *transform);4372png_bytep dp = png_voidcast(png_bytep, tc->dp);4373const unsigned int cbytes = tr->st.ntrans;4374png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);4375const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - cbytes/*safety*/;4376const int copy = dp != sp;43774378/* We expect opaque and transparent pixels to be interleaved but with long4379* sequences of each.4380*/4381debug(!(tc->format & PNG_FORMAT_FLAG_ALPHA) &&4382PNG_TC_PIXEL_DEPTH(*tc) == cbytes << 3);4383tc->invalid_info |= PNG_INFO_tRNS;4384tc->sp = dp;43854386/* Look for pixels that match the transparent value, copying opaque ones as4387* required.4388*/4389do4390{4391const png_const_bytep opaque_start = sp;4392size_t cb;43934394/* Find a transparent pixel, or the end: */4395do4396{4397if (memcmp(sp, tr->st.transparent_pixel, cbytes) == 0) /*transparent*/4398break;4399sp += cbytes;4400}4401while (sp <= ep);44024403cb = sp - opaque_start;44044405/* Copy any opaque pixels: */4406if (cb > 0)4407{4408if (copy)4409memcpy(dp, opaque_start, cb);4410dp += cb;4411}44124413/* Set transparent pixels to the background (this has to be done one-by4414* one; the case where all the bytes in the background are equal is not4415* optimized.)4416*/4417if (sp <= ep) do4418{4419memcpy(dp, tr->st.background_pixel, cbytes);4420sp += cbytes;4421dp += cbytes;4422}4423while (sp <= ep && memcmp(sp, tr->st.transparent_pixel, cbytes) == 0);4424} while (sp <= ep);44254426debug(sp == ep+cbytes);4427# undef png_ptr4428}44294430static void4431png_do_replace_tRNS_8(png_transformp *transform, png_transform_controlp tc)4432/* The single byte version: 8-bit gray */4433{4434# define png_ptr (tc->png_ptr)4435png_transform_background *tr =4436png_transform_cast(png_transform_background, *transform);4437png_bytep dp = png_voidcast(png_bytep, tc->dp);4438png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);4439png_alloc_size_t row_bytes = tc->width;4440const int copy = dp != sp;4441const int transparent_pixel = tr->st.transparent_pixel[0];4442const int background_pixel = tr->st.background_pixel[0];44434444/* We expect opaque and transparent pixels to be interleaved but with long4445* sequences of each.4446*/4447debug(!(tc->format & PNG_FORMAT_FLAG_ALPHA) &&4448PNG_TC_PIXEL_DEPTH(*tc) == 8 && tr->st.ntrans == 1);4449tc->invalid_info |= PNG_INFO_tRNS;4450tc->sp = dp;44514452/* Now search for a byte that matches the transparent pixel. */4453do4454{4455const png_const_bytep tp = png_voidcast(png_const_bytep,4456memchr(sp, transparent_pixel, row_bytes));4457png_alloc_size_t cb;44584459if (tp == NULL) /* all remaining pixels are opaque */4460{4461if (copy)4462memcpy(dp, sp, row_bytes);4463return;4464}44654466cb = tp - sp;4467if (cb > 0) /* some opaque pixels found */4468{4469if (copy)4470memcpy(dp, sp, cb);4471sp = tp;4472dp += cb;4473debug(row_bytes > cb);4474row_bytes -= cb;4475}44764477/* Now count the transparent pixels, this could use strspn but for the4478* moment does not.4479*/4480debug(row_bytes > 0);4481++sp; /* next to check, may be beyond the last */4482while (--row_bytes > 0 && *sp == transparent_pixel) ++sp;44834484cb = sp - tp;4485memset(dp, background_pixel, cb);4486dp += cb;4487} while (row_bytes > 0);4488UNTESTED4489# undef png_ptr4490}44914492static void4493png_do_set_row(png_transformp *transform, png_transform_controlp tc)4494/* This is a no-op transform that both invalidates INFO from args and sets4495* the entire row to the byte given in the top bits.4496*/4497{4498png_bytep dp = png_voidcast(png_bytep, tc->dp);44994500tc->sp = dp;4501memset(dp, (*transform)->args >> 24, PNG_TC_ROWBYTES(*tc));4502}45034504static void4505png_do_replace_tRNS_lbd(png_transformp *transform, png_transform_controlp tc)4506{4507/* This is the 2 or 4 bit depth grayscale case; the 1 bit case is handled by4508* the two routines above and the 8-bit and 16-bit cases by the two before4509* that.4510*4511* The transform contains pixel values that have been expanded to one byte,4512* the code needs to match the tRNS pixel and substitute the background one4513* in each byte.4514*/4515# define png_ptr (tc->png_ptr)4516png_transform_background *tr =4517png_transform_cast(png_transform_background, *transform);4518png_bytep dp = png_voidcast(png_bytep, tc->dp);4519png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);4520png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc);4521const unsigned int copy = sp != dp;4522const png_byte transparent_pixel = tr->st.transparent_pixel[0];4523const png_byte background_pixel = tr->st.background_pixel[0];45244525/* We expect opaque and transparent pixels to be interleaved but with long4526* sequences of each.4527*/4528debug(!(tc->format & PNG_FORMAT_FLAG_ALPHA) &&4529PNG_TC_PIXEL_DEPTH(*tc) < 8 && tr->st.ntrans == 1);4530tc->sp = dp;45314532/* Now search for a byte that contains the transparent pixel4533*4534* NOTE: this is the "strlen" algorithm, I first saw a variant implemented in4535* Acorn RISC iX (strlen) around 1991, almost certainly derived from a4536* suggestion by Alan Mycroft dating from April 27, 1987 (Mycroft was one of4537* the authors of the 'Norcroft' compiler used for RISC iX, and well known to4538* the RISC iX implementors.) See, e.g.:4539*4540* http://bits.stephan-brumme.com/null.html.4541*4542* The exact form used here is the one reported by Brumme; I haven't been4543* able to find the original Mycroft posting, it was probably on comp.arch.4544*4545* The 4-bit and 2-bit versions (probably slower in the 4-bit case than the4546* do-it-by-pixel version, but definately faster once 32-bit handling is4547* implemented):4548*4549* 4 bit: (byte - 0x11) & ~byte & 0x884550* 2 bit: (byte - 0x55) & ~byte & 0xcc4551*4552* The generalizations to 32 bits (8 and 16 pixels per step) should be4553* obvious.4554*4555* This algorithm reads pixels within a byte beyond the end of the row and,4556* potentially, changes the non-existent pixels. This is harmless and not4557* a security risk.4558*/4559if (tc->bit_depth == 4U)4560{4561/* For the moment the algorithm isn't used; there are only two pixels in4562* each byte so it is likely to be quicker to check as below:4563*/4564do4565{4566const png_byte b = *sp++;4567const unsigned int m = b ^ transparent_pixel;45684569if (m == 0U) /* both transparent */4570*dp = background_pixel;45714572else if ((m & 0xF0U) == 0U) /* first transparent */4573*dp = PNG_BYTE((background_pixel & 0xF0U) | (b & 0x0FU));45744575else if ((m & 0x0FU) == 0U) /* second transparent */4576*dp = PNG_BYTE((background_pixel & 0x0FU) | (b & 0xF0U));45774578else if (copy) /* neither transparent */4579*dp = b;45804581++dp;4582} while (sp < ep);4583}45844585else4586{4587affirm(tc->bit_depth == 2U);45884589do4590{4591const png_byte b = *sp++;4592const unsigned int m = b ^ transparent_pixel;45934594if (m == 0U) /* transparent */4595*dp = background_pixel;45964597else if (0xAAU & ((m - 0x55U) & ~m))4598{4599/* One or more pixels transparent */4600const unsigned int mask =4601(m & 0xC0U ? 0xC0U : 0U) |4602(m & 0x30U ? 0x30U : 0U) |4603(m & 0x0CU ? 0x0CU : 0U) |4604(m & 0x03U ? 0x03U : 0U);46054606*dp = PNG_BYTE((b & mask) | (background_pixel & ~mask));4607}46084609else if (copy) /* no transparent pixels */4610*dp = b;46114612++dp;4613} while (sp < ep);4614}46154616# undef png_ptr4617}46184619static void4620png_do_background_with_transparent_GA8(png_transformp *transform,4621png_transform_controlp tc)4622{4623# define png_ptr (tc->png_ptr)4624png_transform_background *tr =4625png_transform_cast(png_transform_background, *transform);4626png_bytep dp = png_voidcast(png_bytep, tc->dp);4627png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);4628const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 1U/*safety*/;4629const png_byte background_pixel = tr->st.background_pixel[0];46304631/* Because this is an alpha format and we are removing the alpha channel we4632* can copy up.4633*/4634debug(tc->bit_depth == 8U && tc->format == PNG_FORMAT_GA &&4635tr->st.ntrans == 1U);4636tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);4637tc->sp = dp;46384639/* Look for pixels that have alpha 0; all others should have alpha 1.0,4640* however they are simply treated as opaque regardless.4641*/4642do4643{4644*dp++ = (sp[1] == 0U) ? background_pixel : sp[0];4645sp += 2U;4646} while (sp < ep);46474648debug(sp == ep+1U);4649# undef png_ptr4650}46514652static void4653png_do_background_with_transparent_GA16(png_transformp *transform,4654png_transform_controlp tc)4655{4656# define png_ptr (tc->png_ptr)4657png_transform_background *tr =4658png_transform_cast(png_transform_background, *transform);4659png_bytep dp = png_voidcast(png_bytep, tc->dp);4660png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);4661const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 3U/*safety*/;46624663debug(tc->bit_depth == 16U && tc->format == PNG_FORMAT_GA &&4664tr->st.ntrans == 2U);4665tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);4666tc->sp = dp;46674668do4669{4670if (sp[2] == 0U && sp[3] == 0U) /* transparent */4671dp[0] = tr->st.background_pixel[0], dp[1] = tr->st.background_pixel[1];46724673else4674dp[0] = sp[0], dp[1] = sp[1];46754676dp += 2U;4677sp += 4U;4678} while (sp < ep);46794680debug(sp == ep+3U);4681# undef png_ptr4682}46834684static void4685png_do_background_with_transparent_GAlbd(png_transformp *transform,4686png_transform_controlp tc)4687/* This is the low-bit-depth gray case, the input is 1, 2 or 4-bit per4688* channel gray-alpha.4689*/4690{4691# define png_ptr (tc->png_ptr)4692png_transform_background *tr =4693png_transform_cast(png_transform_background, *transform);4694png_bytep dp = png_voidcast(png_bytep, tc->dp);4695png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);4696const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc);4697const unsigned int bit_depth = tc->bit_depth;4698const unsigned int mask = (1U << bit_depth) - 1U;4699const unsigned int back = tr->st.background_pixel[0] & mask;4700unsigned int opos, ob, inb;47014702debug(bit_depth < 8U && tc->format == PNG_FORMAT_GA && tr->st.ntrans == 1U);4703tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);4704tc->sp = dp;47054706ob = 0U; /* output byte */4707opos = 0U; /* bit index of previous output pixel (counts down) */4708inb = 0U; /* quiet a GCC 4.8.5 warning */47094710for (;;)4711{4712/* The output is half the size of the input, so we need a new input byte4713* for every 4 bits of output:4714*/4715if (opos == 0U || opos == 4U)4716{4717if (sp >= ep)4718break;47194720inb = *sp++;4721}47224723/* Move to the next *output* pixel, this wraps when bits is 0U: */4724opos = (opos - bit_depth) & 0x7U;47254726/* Extract the whole input pixel to the low bits of a temporary: */4727{4728unsigned int pixel = inb >> ((opos*2U) & 0x7U);47294730/* The alpha channel is second, check for a value of 0: */4731if ((pixel & mask)/* A component*/ == 0U)4732pixel = back;47334734else4735{4736debug((pixel & mask) == mask);4737pixel = (pixel >> bit_depth) & mask; /* G component */4738}47394740ob |= pixel << opos;4741}47424743if (opos == 0U)4744*dp++ = PNG_BYTE(ob), ob = 0U;4745}47464747if (opos != 0U)4748*dp++ = PNG_BYTE(ob);47494750debug(sp == ep);4751# undef png_ptr4752}47534754static void4755png_do_background_with_transparent_RGBA8(png_transformp *transform,4756png_transform_controlp tc)4757{4758# define png_ptr (tc->png_ptr)4759png_transform_background *tr =4760png_transform_cast(png_transform_background, *transform);4761png_bytep dp = png_voidcast(png_bytep, tc->dp);4762png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);4763const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 3U/*safety*/;47644765debug(tc->bit_depth == 8U && tc->format == PNG_FORMAT_RGBA &&4766tr->st.ntrans == 3U);4767tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);4768tc->sp = dp;47694770do4771{4772if (sp[3] == 0U) /* transparent */4773memcpy(dp, tr->st.background_pixel, 3U);47744775else4776memmove(dp, sp, 3U);47774778dp += 3U;4779sp += 4U;4780} while (sp < ep);47814782debug(sp == ep+3U);4783# undef png_ptr4784}47854786static void4787png_do_background_with_transparent_RGBA16(png_transformp *transform,4788png_transform_controlp tc)4789{4790# define png_ptr (tc->png_ptr)4791png_transform_background *tr =4792png_transform_cast(png_transform_background, *transform);4793png_bytep dp = png_voidcast(png_bytep, tc->dp);4794png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);4795const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 7U/*safety*/;47964797debug(tc->bit_depth == 16U && tc->format == PNG_FORMAT_RGBA &&4798tr->st.ntrans == 6U);4799tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);4800tc->sp = dp;48014802do4803{4804if (sp[6] == 0U && sp[7] == 0U) /* transparent */4805memcpy(dp, tr->st.background_pixel, 6U);48064807else4808memmove(dp, sp, 6U);48094810dp += 6U;4811sp += 8U;4812} while (sp < ep);48134814debug(sp == ep+7U);4815# undef png_ptr4816}48174818static void4819png_init_background_transparent(png_transformp *transform,4820png_transform_controlp tc)4821/* Select the correct version of the above routines. */4822{4823# define png_ptr (tc->png_ptr)4824png_transform_background *tr =4825png_transform_cast(png_transform_background, *transform);48264827debug(tc->init == PNG_TC_INIT_FINAL /* never called in 'FORMAT' */ &&4828(tc->format & PNG_FORMAT_FLAG_ALPHA) != 0);48294830/* Now we know the format on which processing will happen so it is possible4831* to generate the correct fill pixel value to use.4832*/4833fill_background_pixel(tr, tc);4834tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);4835tc->invalid_info |= PNG_INFO_sBIT;4836tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A =4837png_check_byte(png_ptr, tc->bit_depth);48384839if (!(tc->format & PNG_FORMAT_FLAG_COLOR))4840{4841if (tc->bit_depth == 8U)4842tr->tr.fn = png_do_background_with_transparent_GA8;48434844else if (tc->bit_depth == 16U)4845tr->tr.fn = png_do_background_with_transparent_GA16;48464847else /* low-bit-depth gray with alpha (not a PNG format!) */4848tr->tr.fn = png_do_background_with_transparent_GAlbd;4849}48504851else /* color */4852{4853if (tc->bit_depth == 8U)4854tr->tr.fn = png_do_background_with_transparent_RGBA8;48554856else4857{4858debug(tc->bit_depth == 16U);4859tr->tr.fn = png_do_background_with_transparent_RGBA16;4860}4861}4862# undef png_ptr4863}48644865/* The calculated values below have the range 0..65535*65535, the output has the4866* range 0..65535, so divide by 65535. Two approaches are given here, one4867* modifies the value in place, the other uses a more complex expression. With4868* gcc on an AMD64 system the in-place approach is very slightly faster.4869*4870* The two expressions are slightly different in what they calculate but both4871* give the exact answer (verified by exhaustive testing.)4872*4873* The macro must be given a png_uint_32 variable (lvalue), normally an auto4874* variable.4875*/4876#ifndef PNG_COMPOSE_DIV_655354877# ifdef PNG_COMPOSE_DIV_EXPRESSION_SUPPORTED4878# define PNG_COMPOSE_DIV_65535(v)\4879(v = ((v + (v>>16) + (v>>31) + 32768U) >> 16))4880# else4881# define PNG_COMPOSE_DIV_65535(v)\4882(v += v >> 16, v += v >> 31, v += 32768U, v >>= 16)4883# endif4884#endif48854886static void4887png_do_background_alpha_GA(png_transformp *transform, png_transform_controlp tc)4888{4889# define png_ptr (tc->png_ptr)4890png_transform_background *tr =4891png_transform_cast(png_transform_background, *transform);4892png_bytep dp = png_voidcast(png_bytep, tc->dp);4893png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);4894const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 3U/*safety*/;4895const unsigned int background = tr->st.background.gray;4896const int copy = (sp != dp);4897const int compose = tr->st.compose_background;48984899affirm(tc->bit_depth == 16U && tc->format == PNG_FORMAT_GA &&4900tr->st.background_bit_depth == 16U);49014902/* If gamma transforms are eliminated this might fail: */4903debug(tr->st.background_gamma == tc->gamma ||4904tr->st.background_gamma == 0 ||4905tc->sBIT_G == 1);49064907tc->sp = tc->dp; /* nothing else changes */49084909do4910{4911const png_uint_32 alpha = (sp[2] << 8) + sp[3];49124913switch (alpha)4914{4915case 0U: /* transparent */4916memset(dp, 0U, 4U);4917break;49184919default:4920{4921png_uint_32 v = ((sp[0] << 8) + sp[1]) * alpha +4922background * (65535U - alpha);49234924PNG_COMPOSE_DIV_65535(v);4925debug(v <= 65535U);4926dp[0] = PNG_BYTE(v >> 8);4927dp[1] = PNG_BYTE(v);4928}49294930if (compose)4931dp[3] = dp[2] = 0xFFU; /* alpha; set to 1.0 */49324933else if (copy)4934{4935dp[2] = PNG_BYTE(alpha >> 8);4936dp[3] = PNG_BYTE(alpha);4937}4938break;49394940case 65535U: /* opaque */4941if (copy)4942memcpy(dp, sp, 4U);4943break;4944}49454946sp += 4U;4947dp += 4U;4948}4949while (sp < ep);49504951debug(sp == ep+3U);4952# undef png_ptr4953}49544955static void4956png_do_background_alpha_RGBA(png_transformp *transform,4957png_transform_controlp tc)4958{4959# define png_ptr (tc->png_ptr)4960png_transform_background *tr =4961png_transform_cast(png_transform_background, *transform);4962png_bytep dp = png_voidcast(png_bytep, tc->dp);4963png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);4964const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 7U/*safety*/;4965const unsigned int bred = tr->st.background.red;4966const unsigned int bgreen = tr->st.background.green;4967const unsigned int bblue = tr->st.background.blue;4968const int copy = (sp != dp);4969const int compose = tr->st.compose_background;49704971affirm(tc->bit_depth == 16U && tc->format == PNG_FORMAT_RGBA &&4972tr->st.background_bit_depth == 16U);49734974debug(tr->st.background_gamma == tc->gamma ||4975tr->st.background_gamma == 0 ||4976(tc->sBIT_R == 1 && tc->sBIT_G == 1 && tc->sBIT_B == 1));49774978tc->sp = tc->dp; /* nothing else changes */49794980do4981{4982const png_uint_32 alpha = (sp[6] << 8) + sp[7];49834984switch (alpha)4985{4986case 0U: /* transparent */4987memset(dp, 0U, 8U);4988break;49894990default:4991{4992const png_uint_32 balpha = (65535U - alpha);4993png_uint_32 r = ((sp[0] << 8) + sp[1]) * alpha + bred * balpha;4994png_uint_32 g = ((sp[2] << 8) + sp[3]) * alpha + bgreen * balpha;4995png_uint_32 b = ((sp[4] << 8) + sp[5]) * alpha + bblue * balpha;49964997PNG_COMPOSE_DIV_65535(r);4998PNG_COMPOSE_DIV_65535(g);4999PNG_COMPOSE_DIV_65535(b);5000debug(r <= 65535U && g <= 65535U && b <= 65535U);5001dp[0] = PNG_BYTE(r >> 8);5002dp[1] = PNG_BYTE(r);5003dp[2] = PNG_BYTE(g >> 8);5004dp[3] = PNG_BYTE(g);5005dp[4] = PNG_BYTE(b >> 8);5006dp[5] = PNG_BYTE(b);5007}50085009if (compose)5010dp[7] = dp[6] = 0xFFU;50115012else if (copy)5013{5014dp[6] = PNG_BYTE(alpha >> 8);5015dp[7] = PNG_BYTE(alpha);5016}5017break;50185019case 65535U: /* opaque */5020if (copy)5021memcpy(dp, sp, 8U);5022break;5023}50245025sp += 8U;5026dp += 8U;5027}5028while (sp < ep);50295030debug(sp == ep+7U);5031# undef png_ptr5032}50335034static void5035png_init_background_alpha_end(png_transformp *transform,5036png_transform_controlp tc)5037/* This is just the last part of png_init_background_alpha (below) */5038{5039# define png_ptr (tc->png_ptr)5040png_transform_background *tr =5041png_transform_cast(png_transform_background, *transform);50425043debug(tc->init == PNG_TC_INIT_FINAL);50445045/* Repeat the tests at the end of png_init_background_alpha: */5046affirm(tc->bit_depth == 16U && (tc->format & PNG_FORMAT_FLAG_ALPHA) != 0);5047debug(tc->gamma == 0 ||5048!png_gamma_significant(png_ptr, tc->gamma, tc_sBIT(tc)));50495050/* tr->st.background_is_gray was filled in by resolve_background_color and5051* records if either the background was a gray value or it was a color5052* value with all the channels equal.5053*/5054if (!tr->st.background_is_gray && !(tc->format & PNG_FORMAT_FLAG_COLOR))5055{5056# ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED5057/* Color background with gray data: this happens when there is a5058* gray to RGB transform in the pipeline but it hasn't happened5059* yet. Unfortunately it has to happen now to be able to do the5060* compose against the colored background.5061*/5062png_push_gray_to_rgb_byte_ops(transform, tc);5063affirm((tc->format & PNG_FORMAT_FLAG_COLOR) != 0);5064return;5065# else /* !GRAY_TO_RGB */5066impossible("gray to RGB"); /* how can this happen? */5067# endif /* !GRAY_TO_RGB */5068}50695070/* The transform happens in two parts, a part to do the arithmetic on5071* pixels where it is required followed by a part to replace transparent5072* pixels. These two parts require different versions of the background5073* pixel. Set up the second part first.5074*5075* This only happens with background composition, otherwise the5076* transparent pixels are already 0 and nothing needs to be done.5077*/5078if (tr->st.compose_background)5079{5080/* The transparent pixel handling happens *after* the data has been5081* re-encoded to the output gamma:5082*/5083png_transform_background *tr_alpha =5084png_transform_cast(png_transform_background,5085png_add_transform(png_ptr, sizeof (png_transform_background),5086png_init_background_transparent, PNG_TR_GAMMA_ENCODE+0xF0U));50875088/* Copy the current state into the new png_transform_background: */5089tr_alpha->st = tr->st;5090tr_alpha->tr.args = tr->tr.args;5091}50925093/* Now it is possible to overwrite tr->st.background with the linear version.5094*/5095gamma_correct_background(tr, tc);50965097/* sBIT informationmust also be invalidated here, because a gamma5098* transform may run before the transparent pixel handling.5099*/5100tc->invalid_info |= PNG_INFO_sBIT;5101tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A =5102png_check_byte(png_ptr, tc->bit_depth);51035104/* And select an appropriate function; there are only two choices: */5105switch (tc->format)5106{5107case PNG_FORMAT_GA:5108/* If the background format is color this indicates that there is a5109* gray to RGB transform missing and we need it to happen before5110* this point!5111*/5112affirm(tr->st.background_is_gray);5113tr->tr.fn = png_do_background_alpha_GA;5114break;51155116case PNG_FORMAT_RGBA:5117if (tr->st.background_is_gray)5118tr->st.background.blue = tr->st.background.green =5119tr->st.background.red = tr->st.background.gray;5120tr->tr.fn = png_do_background_alpha_RGBA;5121break;51225123default:5124NOT_REACHED;5125}5126# undef png_ptr5127}51285129static void5130png_init_background_alpha(png_transformp *transform, png_transform_controlp tc)5131/* This is used when alpha composition is required because the alpha channel5132* may contain values that are between 0 and 1. Because doing alpha5133* composition requires linear arithmetic the data is converted to 16-bit5134* linear, however this means that the background pixel gets converted too5135* and, for 16-bit output, this tends to smash the value. Consequently the5136* algorithm used here is to skip those pixels and use the 'transparent5137* alpha' routines to replace them after the gamma correction step.5138*/5139{5140# define png_ptr (tc->png_ptr)5141png_transform_background *tr =5142png_transform_cast(png_transform_background, *transform);51435144debug(tc->init == PNG_TC_INIT_FINAL);5145/* png_init_background ensures this is true: */5146debug((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0);51475148/* Always push gamma transforms; don't try to optimize the case when they5149* aren't needed because that would be an attempt to duplicate the tests in5150* png_init_gamma and it might now work reliably.5151*5152* Need to push the to-linear transform *before* this transform and add gamma5153* correction afterward to get back to the screen format. Do the afterward5154* bit first to avoid complexity over *transform:5155*/5156{5157png_transform_gamma *tr_end = add_gamma_transform(png_ptr,5158PNG_TR_GAMMA_ENCODE, tc->gamma, 0U/*bit depth*/, 0/*default*/);51595160/* Encoding the alpha channel happens in the last step, so this needs to5161* be set here. Notice that in C++ terms we are very friendly with5162* png_transform_gamma.5163*/5164tr_end->encode_alpha = tr->st.encode_alpha;5165tr_end->optimize_alpha = tr->st.optimize_alpha;5166}51675168{5169/* Now add tr_gamma before this transform, expect it to go in at5170* *transform or the whole thing won't work:5171*/5172png_transform_gamma *tr_gamma = png_transform_cast(png_transform_gamma,5173png_push_transform(png_ptr, sizeof (png_transform_gamma),5174png_init_gamma, transform, NULL/*don't run init*/));51755176/* This must happen before we run png_gamma_init: */5177tr_gamma->to_gamma = PNG_FP_1;5178tr_gamma->to_bit_depth = 16U;51795180/* Now run the this transform; it was pushed before this one, so it gets5181* to do its init first and this function must return as the caller will5182* immediately call here again.5183*/5184debug(*transform == &tr_gamma->tr);5185png_init_gamma(transform, tc);5186affirm(tc->bit_depth == 16U &&5187(tc->format & PNG_FORMAT_FLAG_ALPHA) != 0);5188/* This is only a 'debug' because it needs to replicate the test in5189* png_init_gamma and that is easy to get wrong (a harmless mistake).5190*/5191debug(tc->gamma == 0 ||5192!png_gamma_significant(png_ptr, tc->gamma, tc_sBIT(tc)));5193}51945195/* A transform was pushed, so this transform init will be run again: */5196tr->tr.fn = png_init_background_alpha_end;5197# undef png_ptr5198}51995200/* Handle alpha and tRNS via a background color */5201static void5202png_init_background(png_transformp *transform, png_transform_controlp tc)5203{5204/* This init function is called right at the start, this means it can get at5205* the tRNS values if appropriate. If not the RGB to gray transform comes5206* next followed by PNG_TR_COMPOSE_ALPHA, which actually does the non-tRNS5207* work.5208*/5209png_structp png_ptr = tc->png_ptr;5210png_transform_background *tr =5211png_transform_cast(png_transform_background, *transform);52125213if (tc->init == PNG_TC_INIT_FORMAT)5214{5215/* Background composition removes the alpha channel, so the other5216* operations become irrelevant:5217*/5218if (tr->st.compose_background)5219tr->st.associate_alpha = tr->st.encode_alpha = tr->st.optimize_alpha =52200U;52215222else if (!tr->st.associate_alpha)5223{5224/* There is nothing to do, delete the whole transform. */5225tr->tr.fn = NULL;5226return;5227}52285229/* Else alpha association ('pre-multiplication') which is achieved by5230* composing on a 0 background. The background color will be black (all5231* zeros) and the background gamma will be zero.5232*/52335234/* Because we are in PNG_TC_INIT_FORMAT no other transforms will have been5235* inserted between this one and an rgb-to-gray transform, so we can find5236* out if rgb-to-gray has been requested:5237*/5238tr->st.rgb_to_gray = tr->tr.next != NULL &&5239tr->tr.next->order == PNG_TR_RGB_TO_GRAY;52405241if ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0)5242{5243/* Associated alpha does not strip the alpha channel! */5244if (tr->st.compose_background)5245tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);5246}52475248else if (!tc->palette &&5249png_ptr->num_trans == 1 && !(tc->invalid_info & PNG_INFO_tRNS))5250{5251/* tRNS will be expanded, or handled */5252tc->invalid_info |= PNG_INFO_tRNS;5253if (!tr->st.compose_background)5254{5255tc->format |= PNG_FORMAT_FLAG_ALPHA;5256/* And in this case, only, because we are adding an alpha channel we5257* need to have a channel depth of at least 8:5258*/5259if (tc->bit_depth < 8U)5260tc->bit_depth = 8U;5261}5262}52635264else /* no transparent pixels to change */5265tr->tr.fn = NULL;5266}52675268else /* PNG_TC_INIT_FINAL */5269{5270png_fixed_point correction;52715272debug(tc->init == PNG_TC_INIT_FINAL &&5273((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0 ||5274(!tc->palette && png_ptr->num_trans == 1 &&5275!(tc->invalid_info & PNG_INFO_tRNS))));52765277/* The screen gamma is known, so the background gamma can be found, note5278* that both the gamma values used below will be 0 if no gamma information5279* was in the PNG and no gamma information has been provided by5280* png_set_gamma or png_set_alpha_mode.5281*/5282switch (tr->st.background_gamma)5283{5284case PNG_BACKGROUND_GAMMA_FILE:5285/* png_init_transform_control has already found the file gamma,5286* and because this is the first arithmetic transformation5287* nothing has changed it.5288*/5289tr->st.background_gamma = tc->gamma;5290break;52915292case PNG_BACKGROUND_GAMMA_SCREEN:5293tr->st.background_gamma = png_ptr->row_gamma;5294break;52955296default:5297/* already set */5298break;5299}53005301/* Work out what the background color is, this only depends on 'tc' for5302* palette information, so it can be done now before we know the actual5303* bit_depth/format that will be required:5304*/5305resolve_background_color(tr, tc);53065307/* Is this format compatible with the current row data? If it is then it5308* is possible to avoid the arithmetic if no alpha processing is required.5309* This is a useful optimization because PNG files with just transparent5310* pixels and no alpha are common.5311*5312* NOTE: if an RGB-to-gray transform is present this is fine so long as5313* the background is gray, otherwise (non-gray background) there is a5314* following gray-to-RGB transform and the now gray image must be5315* composited on a color background.5316*/5317if (tr->st.compose_background /* alpha channel stripped */ &&5318(tr->st.background_is_gray ||5319((tc->format & PNG_FORMAT_FLAG_COLOR) != 0 && !tr->st.rgb_to_gray))5320/* color compatible */ &&5321tc->bit_depth >= tr->st.background_bit_depth5322/* bit depth compatible */ &&5323(tc->transparent_alpha ||5324(!tc->palette && png_ptr->num_trans == 1 &&5325!(tc->invalid_info & PNG_INFO_tRNS)))5326/* no alpha processing */ &&5327png_gamma_equal(png_ptr, tc->gamma, png_ptr->row_gamma, &correction,5328tc->bit_depth) /* gamma compatible (so no gamma processing) */)5329{5330/* How the operation gets performed depends on whether the current data5331* has an alpha channel or not.5332*/5333if ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0)5334{5335affirm(tc->transparent_alpha);5336/* This init routine does the sBIT handling: */5337png_init_background_transparent(transform, tc);5338}53395340else if (!tc->palette && png_ptr->num_trans == 1 &&5341!(tc->invalid_info & PNG_INFO_tRNS))5342{5343/* The background pixel needs to be filled in now; no more init5344* routines are called in this case. It is important to delay this5345* as late as possible because it needs to know the actual tc format5346* that must be used.5347*/5348fill_background_pixel(tr, tc);53495350debug(!(png_ptr->color_type & PNG_COLOR_MASK_PALETTE));53515352/* The pixel depth should not have been changed yet: */5353debug(PNG_PIXEL_DEPTH(*png_ptr) == PNG_TC_PIXEL_DEPTH(*tc));53545355/* The transparent_pixel value needs to be filled in. */5356affirm(tr->st.ntrans ==5357fill_transparent_pixel(png_ptr, tr->st.transparent_pixel));53585359/* The whole operation is a no-op if the transparent pixel and the5360* background pixel match, even in the associated alpha case where5361* both will be 0 throughout.5362*5363* NOTE: for palette images this test happens in the caching5364* operation, so the answer is still correct.5365*5366* NOTE: for low bit depth gray both 'transparent_pixel' and5367* 'background_pixel' have been expanded to fill a byte, so this5368* works.5369*/5370if (memcmp(tr->st.transparent_pixel, tr->st.background_pixel,5371tr->st.ntrans) == 0)5372tr->tr.fn = NULL;53735374/* Then the processing function depends on the pixel size: */5375else if (tr->st.ntrans > 1U)5376tr->tr.fn = png_do_replace_tRNS_multi;53775378else if (tc->bit_depth == 8U)5379tr->tr.fn = png_do_replace_tRNS_8;53805381else if (tc->bit_depth == 1U)5382{5383/* This is the silly case: the replacement pixel does not match5384* the transparent pixel (handled above) so either all the '0'5385* bits are replaced by '1' or all the '1' bits are replaced by5386* '0':5387*/5388png_uint_32 args = tr->st.background_pixel[0];53895390args <<= 24;5391args |= PNG_INFO_tRNS | PNG_INFO_sRGB;5392tr->tr.args = args;5393tr->tr.fn = png_do_set_row;5394}53955396else5397tr->tr.fn = png_do_replace_tRNS_lbd;53985399tc->invalid_info |= PNG_INFO_tRNS | PNG_INFO_sBIT;5400tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A =5401png_check_byte(png_ptr, tc->bit_depth);5402}54035404else5405{5406/* Nothing to do; should have been eliminated before! */5407tr->tr.fn = NULL;5408NOT_REACHED;5409}5410}54115412else /* alpha, or maybe gamma, processing required */5413{5414/* Alpha case, add an appropriate transform; this has to be done5415* *after* the RGB-to-gray case so move the transform info there:5416*/5417png_transform_background *tr_alpha =5418png_transform_cast(png_transform_background,5419png_add_transform(png_ptr, sizeof (png_transform_background),5420png_init_background_alpha, PNG_TR_COMPOSE_ALPHA));54215422/* Copy the current state into the new png_transform_background: */5423tr_alpha->st = tr->st;5424tr_alpha->tr.args = tr->tr.args;54255426/* The rest of the init occurs later; this transform is no longer5427* needed.5428*/5429tr->tr.fn = NULL;54305431/* Ensure that png_init_background_alpha gets an alpha channel, this5432* needs to happen here because otherwise intervening transforms can5433* invalidate tRNS.5434*/5435tc->expand_tRNS = 1U;5436if (tr->st.compose_background)5437tc->strip_alpha = 0U;54385439/* And push the expand: */5440(void)push_gamma_expand(transform, tc, 1/*need alpha*/);54415442/* Regardless of whether anything got pushed the following should now5443* be true:5444*/5445affirm((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0 &&5446tc->bit_depth >= 8U);5447}5448}5449}54505451void PNGFAPI5452png_set_background_fixed(png_structrp png_ptr,5453png_const_color_16p background_color, int background_gamma_code,5454int need_expand, png_fixed_point background_gamma)5455{5456if (png_ptr != NULL)5457{5458if (background_color != NULL)5459{5460png_transform_background *tr =5461png_transform_cast(png_transform_background,5462png_add_transform(png_ptr, sizeof (png_transform_background),5463png_init_background, PNG_TR_COMPOSE));54645465/* This silently overwrites the information if png_set_background is5466* called more than once.5467*/5468tr->st.background = *background_color;5469tr->st.need_expand = need_expand != 0;5470tr->st.compose_background = 1U; /* png_set_background called */5471switch (background_gamma_code)5472{5473case PNG_BACKGROUND_GAMMA_SCREEN:5474case PNG_BACKGROUND_GAMMA_FILE:5475tr->st.background_gamma = background_gamma_code;5476break;54775478case PNG_BACKGROUND_GAMMA_UNIQUE:5479if (background_gamma >= 16 && background_gamma <= 625000000)5480{5481tr->st.background_gamma = background_gamma;5482break;5483}54845485png_app_error(png_ptr, "gamma value out of range");5486/* FALL THROUGH */5487default:5488png_app_error(png_ptr, "invalid gamma information");5489tr->st.background_gamma = (need_expand ?5490PNG_BACKGROUND_GAMMA_FILE : PNG_BACKGROUND_GAMMA_SCREEN);5491break;5492}5493}54945495else5496png_app_error(png_ptr, "missing background color");5497}5498}54995500# ifdef PNG_FLOATING_POINT_SUPPORTED5501void PNGAPI5502png_set_background(png_structrp png_ptr,5503png_const_color_16p background_color, int background_gamma_code,5504int need_expand, double background_gamma)5505{5506png_set_background_fixed(png_ptr, background_color, background_gamma_code,5507need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));5508}5509# endif /* FLOATING_POINT */5510#endif /* READ_BACKGROUND */55115512#ifdef PNG_READ_ALPHA_MODE_SUPPORTED5513void PNGFAPI5514png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,5515png_fixed_point output_gamma)5516{5517if (png_ptr != NULL)5518{5519/* Check the passed in output_gamma value; it must be valid and it must be5520* converted to the reciprocal for use below:5521*/5522output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);55235524if (output_gamma > 0) /* Else an app_error has been signalled. */5525{5526/* Only set the colorspace gamma if it has not already been set (this5527* has the side effect that the gamma in a second call to5528* png_set_alpha_mode will be ignored.)5529*/5530if ((png_ptr->colorspace.flags &5531(PNG_COLORSPACE_INVALID | PNG_COLORSPACE_HAVE_GAMMA)) !=5532PNG_COLORSPACE_HAVE_GAMMA)5533{5534/* The default file gamma is the output gamma encoding: */5535png_ptr->colorspace.gamma = output_gamma;5536if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)5537png_ptr->colorspace.flags = PNG_COLORSPACE_HAVE_GAMMA;5538else5539png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;5540}55415542/* Always set the output gamma, note that it may be changed to PNG_FP_15543* for the associated alpha support. This means that the last call to5544* png_set_gamma[_fixed] or png_set_alpha_mode sets the output gamma,5545* which is probably what is expected.5546*/5547{5548png_transform_gamma *tr_gamma = add_gamma_transform(png_ptr,5549PNG_TR_GAMMA_ENCODE,5550mode == PNG_ALPHA_ASSOCIATED ? PNG_FP_1 : output_gamma, 0U,55511/*force*/);55525553/* Get a background transform and set the appropriate fields.5554*5555* png_set_background removes the alpha channel so it effectively5556* disbles png_set_alpha_mode however png_set_alpha_mode is still5557* useful to set a default gamma value.5558*/5559png_transform_background *tr =5560png_transform_cast(png_transform_background,5561png_add_transform(png_ptr, sizeof (png_transform_background),5562png_init_background, PNG_TR_COMPOSE));55635564/* There are really 8 possibilities here, composed of any5565* combination of:5566*5567* premultiply the color channels5568* do not encode non-opaque pixels (leave as linear)5569* encode the alpha as well as the color channels5570*5571* The differences disappear if the input/output ('screen') gamma is5572* 1.0, because then the encoding is a no-op and there is only the5573* choice of premultiplying the color channels or not.5574*/5575switch (mode)5576{5577case PNG_ALPHA_PNG: /* default: png standard */5578/* No compose, but it may be set by png_set_background! This5579* is the only mode that doesn't interfere with what5580* png_set_background does.5581*/5582tr->st.associate_alpha = 0U;5583tr_gamma->encode_alpha = tr->st.encode_alpha = 0U;5584tr_gamma->optimize_alpha = tr->st.optimize_alpha = 0U;5585break;55865587case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */5588tr->st.associate_alpha = 1U;5589tr_gamma->encode_alpha = tr->st.encode_alpha = 0U;5590tr_gamma->optimize_alpha = tr->st.optimize_alpha = 0U;5591break;55925593case PNG_ALPHA_OPTIMIZED:5594/* associated with opaque pixels having the given gamma and5595* non-opaque pixels being linear.5596*/5597tr->st.associate_alpha = 1U;5598tr_gamma->encode_alpha = tr->st.encode_alpha = 0U;5599tr_gamma->optimize_alpha = tr->st.optimize_alpha = 1U;5600/* output_gamma records the encoding of opaque pixels! */5601break;56025603case PNG_ALPHA_BROKEN:5604/* associated+non-linear+alpha encoded */5605tr->st.associate_alpha = 1U;5606tr_gamma->encode_alpha = tr->st.encode_alpha = 1U;5607tr_gamma->optimize_alpha = tr->st.optimize_alpha = 0U;5608break;56095610default:5611png_app_error(png_ptr, "invalid alpha mode");5612/* A return at this point is safe; if a background transform5613* was created the init routine will remove it because5614* nothing is set.5615*/5616break;5617} /* alpha mode switch */5618} /* add gamma and background transforms */5619} /* valid output gamma */5620} /* png_ptr != NULL */5621}56225623#ifdef PNG_FLOATING_POINT_SUPPORTED5624void PNGAPI5625png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)5626{5627png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,5628output_gamma));5629}5630#endif /* FLOATING_POINT */5631#endif /* READ_ALPHA_MODE */56325633#ifdef PNG_READ_TRANSFORMS_SUPPORTED5634typedef struct5635{5636png_transform tr;5637png_transform_control tc;5638union5639{5640png_uint_32 u32[1]; /* ensure alignment */5641png_uint_16 u16[1];5642png_byte b8[1];5643} cache;5644} png_transform_cache;56455646#define png_transform_cache_size(size)\5647(offsetof(png_transform_cache, cache)+(size))5648#define png_transform_cache_cast(pointer,size)\5649png_voidcast(png_transform_cache*,\5650png_transform_cast_check(png_ptr, PNG_SRC_LINE, (pointer),\5651png_transform_cache_size(size)))5652/* This is like png_transform_cast except that 'size' is the size of the5653* cache part in the above structure and the type returned is always5654* 'png_transform_cache*'.5655*/56565657/* Functions to handle the cache operation. These don't do any initialization;5658* that happens below when PNG_TC_INIT_FINAL is being run on the whole list.5659* These functions are only implemented for read so the transform control5660* source and destination are always aligned.5661*5662* First some utility functions:5663*/5664static void5665png_transform_control_cp(png_transform_controlp tcDest,5666png_const_transform_controlp tcSrc)5667{5668/* Copy tcSrc over tcDest without overwriting the information specific to the5669* row being transformed.5670*/5671png_structp png_ptr = tcDest->png_ptr;5672png_const_voidp sp = tcDest->sp;5673png_voidp dp = tcDest->dp;5674png_uint_32 width = tcDest->width;5675unsigned int init = tcDest->init;56765677*tcDest = *tcSrc;56785679tcDest->png_ptr = png_ptr;5680tcDest->sp = sp;5681tcDest->dp = dp;5682tcDest->width = width;5683tcDest->init = png_check_bits(tcDest->png_ptr, init, 2);5684}56855686#if !PNG_RELEASE_BUILD5687static int5688png_transform_control_eq(png_const_transform_controlp tc1,5689png_const_transform_controlp tc2)5690{5691/* Say if *tc1 == *tc2, ignoring differences in uncopied fields and 'cost':5692*/5693return5694# ifdef PNG_READ_GAMMA_SUPPORTED5695tc1->gamma == tc2->gamma &&5696# endif5697tc1->format == tc2->format &&5698tc1->range == tc2->range &&5699tc1->bit_depth == tc2->bit_depth &&5700tc1->caching == tc2->caching &&5701tc1->palette == tc2->palette;5702/* invalid_info, cost, interchannel and channel_add are only set during5703* init, so don't do the compare.5704*/5705}5706#endif /* !RELEASE_BUILD */57075708/* Now the routines that actually perform the transform. There are two basic5709* cases:5710*5711* 1) A cached transform that does not change the pixel size and where the pixel5712* size 8 bits or less. This can be done by a 256-entry single byte lookup5713* table, regardless of the bit depth. Two versions of the code exist, one5714* which just transforms the row, the other which transforms and records the5715* maximum pixel depth.5716*5717* 2) A cached transform that increases pixel depth. The destination pixel5718* depth will always be a multiple of 8 bits, the source pixel will be less5719* than or equal to 8 bits and will be in the PNG native (big endian) layout.5720*/5721#define png_ptr (tc->png_ptr) /* Used in all functions below */5722/* (1): single-byte cached transforms: */5723static void5724do_transform_cache_byte(png_transformp *trIn, png_transform_controlp tc)5725{5726png_transform_cache *tr = png_transform_cache_cast(*trIn, 256U);57275728/* Copy the bytes through the 256-byte LUT: */5729png_bytep dp = png_voidcast(png_bytep, tc->dp);5730png_const_bytep ep = dp + PNG_TC_ROWBYTES(*tc);5731png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);57325733tc->sp = dp;57345735do5736*dp++ = tr->cache.b8[*sp++];5737while (dp < ep);57385739png_transform_control_cp(tc, &tr->tc);5740}57415742/* (2) A cached transform that increases pixel depth.5743*5744* There are six output depth possibilites, all a whole number of bytes:5745*5746* 1 byte, 8 bits: palette or grayscale5747* 2 bytes, 16 bits: 16-bit grayscale or 8-bit gray+alpa5748* 3 bytes, 24 bits: 8-bit RGB5749* 4 bytes, 32 bits: 16-bit gray+alpha or 8-bit RGBA5750* 6 bytes, 48 bits: 16-bit RGB5751* 8 bytes, 64 bits: 16-bit RGBA5752*5753* The input must be 1, 2, 4 or 8-bit gray or palette. The first 1-byte case is5754* handled for 8-bit gray/palette above, so there are 22 possibilities. The5755* function names below are:5756*5757* do_transform_cache_<input-bits>_<output-bits>5758*/5759#define transform_cache_size(ipd,opd) ((((1U << (ipd)) * (opd))+7U) >> 3)5760static void5761do_transform_cache_(png_transformp *trIn, png_transform_controlp tc,5762unsigned int ipd, unsigned int opd)5763/* This is the implementation for unknown ipd, opd, below it is called with5764* fixed values. The purpose of this is to allow the compiler/system builder5765* to decide how to optimize for size vs space vs speed. Note that this5766* implementation, while it would work for 8 bit ipd, is not used in that5767* case.5768*/5769{5770png_transform_cache *tr =5771png_transform_cache_cast(*trIn, transform_cache_size(ipd, opd));57725773png_bytep dp = png_voidcast(png_bytep, tc->dp);5774png_const_bytep ep = dp;5775png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);5776unsigned int s, shift, mask;57775778sp += PNG_TC_ROWBYTES(*tc); /* One byte beyond the end */57795780png_transform_control_cp(tc, &tr->tc);5781dp += PNG_TC_ROWBYTES(*tc);57825783shift = 7U & -(tc->width * ipd);5784/* MSB: shift right required to get last pixel */5785mask = (1U << ipd) - 1U;5786/* Mask to extract a single pixel from the low bits of a byte */5787opd >>= 3;5788/* Output pixel size in bytes */5789s = *--sp;5790/* The first byte; the last byte of the input row */57915792for (;;)5793{5794png_const_bytep opixel = (((s >> shift) & mask)+1U) * opd + tr->cache.b8;5795/* Points to the byte after last byte of the output value */5796unsigned int i;57975798for (i=0; i<opd; ++i)5799*--dp = *--opixel;58005801if (dp <= ep)5802break;58035804shift += ipd; /* To find shift for *previous* pixel */58055806if (shift == 8U)5807s = *--sp, shift = 0U/*right-most pixel*/;5808}58095810debug(dp == ep && shift == 8U-ipd && sp == tc->sp);5811tc->sp = ep; /* start of row, safe even if the above fails */5812}58135814#define do_transform_cache(ipd,opd)\5815static void \5816do_transform_cache_##ipd##_##opd(png_transformp *tr, png_transform_controlp tc)\5817{\5818do_transform_cache_(tr, tc, ipd, opd);\5819}58205821#define TCLOW(opd)\5822do_transform_cache(1,opd)\5823do_transform_cache(2,opd)\5824do_transform_cache(4,opd)58255826TCLOW(8)5827TCLOW(16)5828TCLOW(24)5829TCLOW(32)5830TCLOW(48)5831TCLOW(64)58325833#undef TCLOW5834#undef do_transform_cache58355836static void5837do_transform_cache_8_(png_transformp *trIn, png_transform_controlp tc,5838unsigned int opd)5839/* This is the 8-bit input implementation. */5840{5841png_transform_cache *tr =5842png_transform_cache_cast(*trIn, transform_cache_size(8, opd));58435844png_bytep dp = png_voidcast(png_bytep, tc->dp);5845png_const_bytep ep = dp;5846png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);58475848sp += PNG_TC_ROWBYTES(*tc); /* One byte beyond the end */58495850png_transform_control_cp(tc, &tr->tc);5851dp += PNG_TC_ROWBYTES(*tc);58525853opd >>= 3; /* Output pixel size in bytes */5854do5855{5856png_const_bytep opixel = (*--sp + 1U) * opd + tr->cache.b8;5857/* Points to the byte after last byte of the output value */5858unsigned int i;58595860for (i=0; i<opd; ++i)5861*--dp = *--opixel;5862}5863while (dp > ep);58645865debug(dp == ep && sp == tc->sp);5866tc->sp = ep; /* start of row, safe even if the above fails */5867}58685869#define do_transform_cache(opd)\5870static void \5871do_transform_cache_8_##opd(png_transformp *tr, png_transform_controlp tc)\5872{\5873do_transform_cache_8_(tr, tc, opd);\5874}58755876/* The 8-bit to 8-bit case uses the byte transform code */5877do_transform_cache(16)5878do_transform_cache(24)5879do_transform_cache(32)5880do_transform_cache(48)5881do_transform_cache(64)58825883#undef do_transform_cache58845885#define do_transform_cache(ipd,opd) do_transform_cache_##ipd##_##opd58865887#undef png_ptr58885889typedef struct5890{5891png_transformp *start;5892/* This is a pointer to the pointer to the start of the list being cached,5893* i.e. *start is the first transform in the list.5894*/5895png_transform_control tstart;5896/* This is the transform control at the start; i.e. before (*start)->fn is5897* called. Note that for palette data it will contain the original5898* palette format/bit-depth, not that passed to (*start)->fn which will5899* represent the palette.5900*/5901png_transformp *end;5902png_transform_control tend;5903/* The same data from the end of the run to be cached, i.e. after the5904* function of the transform which *contains* '*end' (end points to5905* tr->next).5906*/5907} png_cache_params, *png_cache_paramsp;59085909static void5910init_caching(png_structp png_ptr, png_transform_controlp tend)5911/* Given an already initialized tend turn on caching if appropriate. */5912{5913/* Handle the colormap case, where a cache is always required: */5914if (tend->format & PNG_FORMAT_FLAG_COLORMAP)5915{5916/* This turns starts the palette caching with the next transform: */5917tend->palette = tend->caching = 1U;5918# ifdef PNG_READ_tRNS_SUPPORTED5919tend->transparent_alpha = png_ptr->transparent_palette;5920# else /* !READ_tRNS */5921tend->transparent_alpha = 0;5922PNG_UNUSED(png_ptr)5923# endif /* !READ_tRNS */5924tend->format = PNG_FORMAT_FLAG_COLOR;5925# ifdef PNG_READ_tRNS_SUPPORTED5926if (png_ptr->num_trans > 0 && !(tend->invalid_info & PNG_INFO_tRNS))5927{5928tend->format |= PNG_FORMAT_FLAG_ALPHA;5929}5930# endif /* READ_tRNS */5931tend->bit_depth = 8U;5932}59335934else if (PNG_TC_PIXEL_DEPTH(*tend) <= 8)5935{5936/* Cacheable pixel transforms; the pixel is less than 8 bits in size so5937* the cache makes sense.5938*5939* TODO: check the cost estimate and the image size to avoid expensive5940* caches of very small images.5941*/5942tend->caching = 1U;5943}59445945/* TODO: handle handle 8-bit GA/RGB/RGBA */5946}59475948static void5949add_cache_transform(png_structp png_ptr, unsigned int order,5950png_transform_fn fn, png_cache_paramsp cp,5951png_const_bytep cache, unsigned int size)5952/* Add a transform from the input format cp->tstart to the output format5953* stored in cp->tend.5954*/5955{5956affirm(size <= 2048U); /* 256 8-byte pixels at most */5957{5958png_transform_cache *tr = png_transform_cache_cast(5959png_add_transform(png_ptr, png_transform_cache_size(size), fn, order),5960size);59615962/* This must have replaced the transform in *cp->start: */5963affirm(&tr->tr == *cp->start);59645965/* Fill in the respective members: */5966tr->tc = cp->tend;5967memcpy(tr->cache.b8, cache, size);59685969/* Skip this transform, because the calling routine has already executed5970* the cache (it could be executed again, just to verify that it works;5971* cp->tstart should be correct.)5972*/5973cp->start = &tr->tr.next;5974}5975}59765977static unsigned int5978setup_palette_cache(png_structp png_ptr, png_byte cache[8*256])5979/* This returns the number of entries in the cache; the width */5980{5981const unsigned int num_palette = png_ptr->num_palette;5982# ifdef PNG_READ_tRNS_SUPPORTED5983unsigned int num_trans = png_ptr->num_trans;5984# endif /* READ_tRNS */5985const png_colorp palette = png_ptr->palette;5986png_bytep p;5987unsigned int i;5988# ifdef PNG_READ_tRNS_SUPPORTED5989const png_bytep trans_alpha = png_ptr->trans_alpha;5990# endif /* READ_tRNS */59915992for (i=0, p=cache; i<num_palette; ++i)5993{5994*p++ = palette[i].red;5995*p++ = palette[i].green;5996*p++ = palette[i].blue;5997# ifdef PNG_READ_tRNS_SUPPORTED5998if (num_trans > 0)5999{6000if (i < num_trans)6001*p++ = trans_alpha[i];60026003else6004*p++ = 0xFFU;6005}6006# endif /* READ_tRNS */6007}60086009return num_palette;6010}60116012static void6013png_remove_PLTE_and_tRNS(png_structrp png_ptr)6014{6015if (png_ptr->palette != NULL)6016png_free(png_ptr, png_ptr->palette);60176018png_ptr->palette = NULL;6019png_ptr->num_palette = 0;60206021# ifdef PNG_READ_tRNS_SUPPORTED6022if (png_ptr->trans_alpha != NULL)6023png_free(png_ptr, png_ptr->trans_alpha);60246025png_ptr->trans_alpha = NULL;6026png_ptr->num_trans = 0;6027# endif /* READ_tRNS */60286029png_ptr->palette_updated = 1U;6030}60316032static void6033update_palette(png_structp png_ptr, png_cache_paramsp cp,6034unsigned int max_depth)6035{6036union6037{6038png_uint_32 u32[1];6039png_uint_16 u16[1]; /* For alignment */6040png_byte b8[8*256]; /* For 16-bit RGBA intermediate */6041} cache;60426043/* The caller only calls this function if the initial transform control had6044* the palette flag set, implying that the original 'format' was a COLORMAP6045* one. Also this can only happen (at present) when starting the transform6046* list, so:6047*/6048affirm((cp->tstart.format & PNG_FORMAT_FLAG_COLORMAP) != 0); /* required */60496050/* Run the whole of the given list on the palette data. PNG_TC_INIT_FINAL6051* has already been run; this is a full run (with init == 0).6052*/6053{6054unsigned int check_depth;6055only_deb(png_transform_control orig = cp->tend;)60566057cp->tend = cp->tstart;6058init_caching(png_ptr, &cp->tend);6059/* And set up tend to actually work out the palette: */6060cp->tend.init = 0U;6061cp->tend.width = setup_palette_cache(png_ptr, cache.b8);6062cp->tend.sp = cache.b8;6063cp->tend.dp = cache.b8;60646065check_depth =6066png_run_this_transform_list_forwards(&cp->tend, cp->start, *cp->end);60676068/* If we get here these two things must be true or there are been some6069* buggy difference of opinion between the INIT code and the actual run:6070*/6071affirm(check_depth == max_depth && cp->tend.palette);60726073/* This should match the passed in final format obtained before, this6074* debug statement detects discrepancies between the init code and the6075* run code:6076*/6077debug(png_transform_control_eq(&cp->tend, &orig));60786079/* Also, expect the palette to still be valid: */6080debug((cp->tend.invalid_info & PNG_INFO_PLTE) == 0);6081}60826083/* The result must be compatible with a PNG palette with respect to bit6084* depth; specifically the expand-16 transform has no effect on palette data.6085*6086* The colormap setting must not have been re-introduced here either; there6087* may be some quantize interactions here, neither can unexpected flags be6088* handled; just COLOR and ALPHA.6089*/6090affirm(cp->tend.bit_depth == 8 &&6091(cp->tend.format & PNG_FORMAT_FLAG_COLORMAP) == 0);60926093/* Remove all the transforms between start(inclusive) and end(exclusive);6094* they have been processed. The effect they had on the transform control6095* is irrelevant because the caller re-instates the settings from tstart.6096*/6097{6098png_transformp list = *cp->start; /* list to free */60996100*cp->start = *cp->end; /* part of list not to be freed */6101*cp->end = NULL; /* terminate the list to be freed */6102cp->end = cp->start; /* else cp->end points to the end of the list! */61036104png_transform_free(png_ptr, &list);6105}61066107/* Adjust the PNG palette and, if required, the tRNS entries. Note that6108* if the transforms stripped the alpha channel from the palette num_trans6109* will get set to 0 here.6110*6111* This is the point where the gamma gets frozen too. The alternative6112* design is to pass palette, tRNS and gamma up the transform chain, but6113* that doesn't work because the palette change would, apparently, have to6114* be repeated on each row. This seems simpler at the cost of a little6115* obscurity; the answer to the question, "Where does the palette get6116* updated?", is "Here!"6117*6118* API CHANGE: (fix): previously the init code would silently overwrite6119* the palette information shared with png_info, breaking the API for6120* png_read_update_info, which doesn't update the info if it isn't called,6121* by changing the palette and maybe tRNS when the first row was read!6122*6123* NOTE: PNG_FORMAT_FLAG_RANGE is lost at this point, even if the palette6124* entries were shifted or inverted. This could be fixed, but it would6125* complicate the libpng API to expose the information.6126*/6127/* Write the transformed palette: */6128{6129png_colorp palette = png_voidcast(png_colorp, png_calloc(png_ptr,6130sizeof (png_color[PNG_MAX_PALETTE_LENGTH])));6131png_const_bytep p;6132const int is_color = (cp->tend.format & PNG_FORMAT_FLAG_COLOR) != 0;6133unsigned int i;6134# ifdef PNG_READ_tRNS_SUPPORTED6135unsigned int num_trans = 0;6136const int do_trans = (cp->tend.format & PNG_FORMAT_FLAG_ALPHA) != 0;6137png_byte trans_alpha[PNG_MAX_PALETTE_LENGTH];6138# endif /* READ_tRNS */61396140memset(palette, 0xFFU, sizeof (png_color[PNG_MAX_PALETTE_LENGTH]));6141png_free(png_ptr, png_ptr->palette);6142png_ptr->palette = palette;61436144for (i=0, p=cache.b8; i<cp->tend.width; ++i)6145{6146if (is_color)6147{6148palette[i].red = *p++;6149palette[i].green = *p++;6150palette[i].blue = *p++;6151}61526153else6154palette[i].blue = palette[i].green = palette[i].red = *p++;61556156# ifdef PNG_READ_tRNS_SUPPORTED6157if (do_trans)6158{6159png_byte a = *p++;6160trans_alpha[i] = a;61616162/* Strip opaque entries from the end: */6163if (a < 0xFFU)6164num_trans = i+1;6165}6166# endif /* READ_tRNS */6167}61686169png_ptr->num_palette = png_check_bits(png_ptr, cp->tend.width, 9);61706171# ifdef PNG_READ_tRNS_SUPPORTED6172if (num_trans > 0)6173{6174png_bytep tRNS = png_voidcast(png_bytep, png_malloc(png_ptr,6175PNG_MAX_PALETTE_LENGTH));61766177memset(tRNS, 0xFFU, PNG_MAX_PALETTE_LENGTH);61786179if (png_ptr->trans_alpha != NULL)6180png_free(png_ptr, png_ptr->trans_alpha);61816182png_ptr->trans_alpha = tRNS;61836184memcpy(tRNS, trans_alpha, num_trans);6185png_ptr->num_trans = png_check_bits(png_ptr, num_trans, 9);6186}6187# endif /* READ_tRNS */6188}61896190/* NOTE: the caller sets cp->start to cp->end and cp->tend to cp->tstart,6191* this causes processing to continue with the palette format and the6192* first unprocessed transform. The reset of the transform control loses the6193* gamma information as well, of course, as any information about the palette6194* and tRNS changes (such as the RANGE flags).6195*6196* The following ensures that png_read_update_info knows to update the6197* palette in png_info (which is no longer shared).6198*/6199png_ptr->palette_updated = 1U;6200}62016202/* These structure and the save/restore routines that follow it exist to save6203* data from a png_transform_control that is specific to the sample encoding of6204* the PNG data, rather than the row format itself.6205*/6206typedef struct6207{6208# ifdef PNG_READ_GAMMA_SUPPORTED6209png_fixed_point gamma;6210# endif6211png_byte sBIT_R;6212png_byte sBIT_G;6213png_byte sBIT_B;6214png_byte sBIT_A; /* Signnificant bits in the row channels. */6215unsigned int invalid_info; /* PNG_INFO_* for invalidated chunks */6216} png_tc_channel_data;62176218static void6219save_cp_channel_data(png_tc_channel_data *save, png_const_transform_controlp tc)6220{6221# ifdef PNG_READ_GAMMA_SUPPORTED6222save->gamma = tc->gamma;6223# endif /* READ_GAMMA */62246225/* The sBIT information and the list of invalidated chunks must also be6226* preserved:6227*/6228save->sBIT_R = tc->sBIT_R;6229save->sBIT_G = tc->sBIT_G;6230save->sBIT_B = tc->sBIT_B;6231save->sBIT_A = tc->sBIT_A;6232save->invalid_info = tc->invalid_info;6233}62346235static void6236restore_cp_channel_data(png_transform_controlp tc,6237const png_tc_channel_data *save)6238/* Reverse the above */6239{6240# ifdef PNG_READ_GAMMA_SUPPORTED6241tc->gamma = save->gamma;6242# endif /* READ_GAMMA */62436244tc->sBIT_R = save->sBIT_R;6245tc->sBIT_G = save->sBIT_G;6246tc->sBIT_B = save->sBIT_B;6247tc->sBIT_A = save->sBIT_A;6248tc->invalid_info = save->invalid_info;6249}62506251static void6252make_cache(png_structp png_ptr, png_cache_paramsp cp, unsigned int max_depth)6253{6254/* At present the cache is just a byte lookup table. We need the original6255* pixel depth to work out how big the working buffer needs to be.6256*/6257const unsigned int ipd = PNG_TC_PIXEL_DEPTH(cp->tstart);6258const unsigned int opd = PNG_TC_PIXEL_DEPTH(cp->tend);6259unsigned int order; /* records position of start transform */6260unsigned int width; /* width of cache in pixels */6261png_tc_channel_data save; /* Record of the final channel info */6262union6263{6264png_uint_32 u32[1];6265png_uint_16 u16[1]; /* For alignment */6266png_byte b8[8*256]; /* For 16-bit RGBA */6267} cache;62686269debug(cp->tend.init == PNG_TC_INIT_FINAL);6270affirm(opd <= 64 && max_depth <= 64); /* or the cache is not big enough */6271affirm(ipd == opd || (opd & 0x7U) == 0);62726273if ((cp->tstart.format & PNG_FORMAT_FLAG_COLORMAP) != 0)6274width = setup_palette_cache(png_ptr, cache.b8);62756276else switch (ipd)6277{6278/* The input to the cache is the full range of possible pixel values: */6279case 1:6280/* 2 1-bit pixels, MSB first */6281cache.b8[0] = 0x40U;6282width = 2;6283break;62846285case 2:6286/* 4 2-bit pixels, MSB first */6287cache.b8[0] = 0x1BU;6288width = 4;6289break;62906291case 4:6292/* 16 4-bit pixels, MSB first */6293cache.b8[0] = 0x01U;6294cache.b8[1] = 0x23U;6295cache.b8[2] = 0x45U;6296cache.b8[3] = 0x67U;6297cache.b8[4] = 0x89U;6298cache.b8[5] = 0xABU;6299cache.b8[6] = 0xCDU;6300cache.b8[7] = 0xEFU;6301width = 16;6302break;63036304case 8:6305/* 256 8-bit pixels */6306{6307unsigned int i;63086309for (i=0; i<256; ++i)6310cache.b8[i] = PNG_BYTE(i);6311}6312width = 256;6313break;63146315default:6316impossible("cache input bit depth");6317}63186319/* Reset the transform control to run the transforms on this data, but save6320* the channel info because the row processing functions do not always6321* write it.6322*/6323save_cp_channel_data(&save, &cp->tend);6324cp->tend = cp->tstart;6325init_caching(png_ptr, &cp->tend);6326/* And set tend to work out the result of transforming each possible pixel6327* value:6328*/6329cp->tend.init = 0U;6330cp->tend.width = width;6331cp->tend.sp = cache.b8;6332cp->tend.dp = cache.b8;63336334{6335unsigned int check_depth =6336png_run_this_transform_list_forwards(&cp->tend, cp->start, *cp->end);63376338/* This must not change: */6339affirm(PNG_TC_PIXEL_DEPTH(cp->tend) == opd && check_depth == max_depth);6340}63416342/* Restore the potentially lost channel data. */6343restore_cp_channel_data(&cp->tend, &save);63446345/* This is all the information required to cache the set of transforms6346* between 'start' and 'end'. We take the transformed pixels and make a6347* cache transform of them. The cache transform skips the work, transforms6348* the row, and sets the tranform_control to (a copy of) cp->tend.6349*6350* Remove all the transforms between start(inclusive) and end(exclusive);6351* they have been processed. The effect they had on the transform control6352* is irrelevant because the caller re-instates the settings from tstart.6353*/6354{6355png_transformp list = *cp->start; /* list to free */63566357*cp->start = *cp->end; /* part of list not to be freed */6358*cp->end = NULL; /* terminate the list to be freed */6359cp->end = NULL; /* reset below */63606361order = list->order; /* used below when adding the cache transform */6362png_transform_free(png_ptr, &list);6363}63646365/* Make the required cache, as enumerated above there are 22 possibilities,6366* this selects between them, fixes up the cache for the 'byte' cases (where6367* multiple pixels can be handled byte-by-byte) and selects the correct6368* transform function.6369*/6370if (ipd == opd)6371{6372/* We already know that ipd is <= 8 bits, so we can expand this case to6373* the byte transform. The complexity is that for ipd < 8 bits we only6374* have information for individual pixel values and these may be6375* pixel-swapped within the byte.6376*/6377if (ipd < 8)6378{6379const int lsb = (cp->tend.format & PNG_FORMAT_FLAG_SWAPPED) != 0;6380unsigned int ishift, b;6381png_byte bcache[256];63826383switch (ipd)6384{6385case 1: ishift = 3U; break;6386case 2: ishift = 2U; break;6387case 4: ishift = 1U; break;6388default: impossible("ipd");6389}63906391/* Work out the right answer for each byte of pixels: */6392for (b=0U; b<256U; ++b)6393{6394unsigned int o = 0U; /* output byte */6395unsigned int p = 8U; /* right shift to find input pixel */63966397do6398{6399unsigned int q = ((1U<<ipd)-1U) & (b >> (p-=ipd));6400/* The input pixel. For a palette this value might be outside6401* the range of palette indices, in which case simply insert6402* '0':6403*/6404if (q < width)6405{6406unsigned int r = cache.b8[q >> ishift];6407r >>= ((lsb ? q : ~q) & ((1U<<ishift)-1U)) << (3U-ishift);6408r &= ((1U<<ipd)-1U);6409o |= r << (lsb ? (8U-ipd)-p : p);6410}64116412else6413{6414UNTESTED6415}6416}6417while (p != 0U);64186419bcache[b] = png_check_byte(png_ptr, o);6420}64216422/* This is a byte transform, with the optional check-for-invalid-index6423* functionality.6424*/6425add_cache_transform(png_ptr, order, do_transform_cache_byte, cp,6426bcache, 256U);6427}64286429else /* ipd == 8 */6430add_cache_transform(png_ptr, order, do_transform_cache_byte, cp,6431cache.b8, 256U);6432}64336434else6435{6436/* opd is a whole number of bytes, ipd is 1, 2, 4 or 8 and not equal to6437* opd.6438*/6439png_transform_fn fn;64406441# define C(ipd,opd) ((ipd) + 8*(opd))6442switch (C(ipd,opd))6443{6444# define CASE(ipd,opd)\6445case C(ipd,opd): fn = do_transform_cache(ipd,opd); break64466447CASE(1,8);6448CASE(2,8);6449CASE(4,8);6450/* No 8,8 */64516452# define CASES(opd)\6453CASE(1,opd);\6454CASE(2,opd);\6455CASE(4,opd);\6456CASE(8,opd)64576458CASES(16);6459CASES(24);6460CASES(32);6461CASES(48);6462CASES(64);6463# undef CASES6464# undef CASE64656466default:6467impossible("cache bit depths");6468}6469# undef C64706471/* In the event that the cache is not the full width implied by ipd zero6472* the remaining bytes for security; otherwise they get copied into the6473* cache transform and might get used. (Specifically if there is an6474* out-of-range palette index they do get used!)6475*/6476{6477unsigned int size = transform_cache_size(ipd, opd);6478png_alloc_size_t cachebytes = PNG_TC_ROWBYTES(cp->tend);64796480affirm(cachebytes <= sizeof cache.b8);64816482if (cachebytes < size)6483memset(cache.b8+cachebytes, 0, size - cachebytes);64846485add_cache_transform(png_ptr, order, fn, cp, cache.b8, size);6486}6487}64886489/* Because a transform was inserted cp->end needs to be set to the new6490* pointer to the original end. add_cache_transform sets cp->start to this,6491* so:6492*/6493cp->end = cp->start;64946495/* This invalidates the palette if that is what was cached because the6496* palette and, if present, tRNS chunk did not get updated above.6497*/6498if (cp->tstart.palette)6499png_remove_PLTE_and_tRNS(png_ptr);6500}65016502static void restore_cp(png_cache_paramsp cp)6503{6504/* A utility to restore cp->tstart by copying it into cp->tend. This is used6505* both in the palette case when restoring the transform control for the6506* indexed data and in the case where no transforms were cached. It6507* preserves the color-channel-specific data from cp->tend because in either6508* case it is possible for this data to be modified without preserving any6509* transforms, e.g. if only the gamma is changed but no gamma transform is6510* retained because the change was not significant.6511*/6512png_tc_channel_data save;65136514save_cp_channel_data(&save, &cp->tend);6515cp->tend = cp->tstart;6516restore_cp_channel_data(&cp->tend, &save);6517}65186519static void6520handle_cache(png_structp png_ptr, png_cache_paramsp cp, unsigned int max_depth)6521{6522/* There is nothing to do if there are no transforms between 'start' and6523* 'end':6524*/6525if (cp->start != cp->end)6526{6527only_deb(png_transformp tr_check = *cp->end;)65286529/* libpng doesn't currently implement any pixel size of more than 64 bits6530* so:6531*/6532affirm(max_depth <= 64);65336534if (cp->tend.palette)6535{6536/* The transforms being cached apply to the palette, the following6537* transforms will apply to the original index data and the transformed6538* data must be used to update the palette:6539*/6540if (cp->tend.init == PNG_TC_INIT_FINAL)6541update_palette(png_ptr, cp, max_depth);65426543cp->start = cp->end;6544restore_cp(cp); /* reset to palette data */6545}65466547else6548{6549/* Continue with the transform control in cp.tend; even if there was6550* palette data in cp.tstart it has been expanded.6551*/6552if (cp->tend.init == PNG_TC_INIT_FINAL)6553make_cache(png_ptr, cp, max_depth);65546555cp->tstart = cp->tend; /* keep current context */6556}65576558debug(tr_check == *cp->end);6559}65606561else /* no transforms cached */6562restore_cp(cp); /* removes any palette caching info */6563}65646565#ifdef PNG_READ_tRNS_SUPPORTED6566static void6567check_tRNS_for_alpha(png_structrp png_ptr)6568{6569unsigned int num_trans = png_ptr->num_trans;65706571debug(png_ptr->color_type == PNG_COLOR_TYPE_PALETTE);65726573while (num_trans > 0)6574{6575{6576const png_byte trans = png_ptr->trans_alpha[--num_trans];65776578if (trans == 0xFFU)6579continue;65806581if (trans > 0U)6582return; /* Palette has at least one entry >0, <0xff */6583}65846585/* There is some point to the tRNS chunk; it has a non-opaque entry, this6586* code could truncate it but there is no obvious performance advantage to6587* doing this.6588*/6589while (num_trans > 0)6590{6591const png_byte trans = png_ptr->trans_alpha[--num_trans];65926593if (trans > 0U && trans < 0xFFU)6594return;6595}65966597/* Here if the above did not find an entry >0 && <0xFFU but did find a6598* transparent entry (0u). Record this.6599*/6600png_ptr->transparent_palette = 1U;6601return;6602}66036604/* All entries opaque; remove the tRNS data: */6605// TODO: This optimization doesn't handle adding it back if RGBA is requested.6606// See PPSSPP issue #14628.6607//png_ptr->num_trans = 0U;6608}6609#endif /* READ_tRNS */66106611unsigned int /* PRIVATE */6612png_read_init_transform_mech(png_structp png_ptr, png_transform_controlp tc)6613/* This is called once for each init stage (PNG_TC_INIT_FORMAT and6614* PNG_TC_INIT_FINAL) to run the transform list forwards, returning the6615* maximum depth required to process the row. It handles caching of the6616* transforms and the processing of the palette for color-mapped PNG data.6617*/6618{6619png_transformp *list = &png_ptr->transform_list;6620unsigned int max_depth, cache_start_depth;6621png_cache_params cp;66226623/* PNG color-mapped data must be handled here so that the palette is updated6624* correctly. png_set_palette_to_rgb causes the palette flag to be removed6625* from the transform control but does no other change. png_set_quantize6626* causes 8-bit RGB, RGBA or palette data to be converted into palette6627* indices, setting the palette flag.6628*/6629# ifdef PNG_READ_tRNS_SUPPORTED6630/* This happens once at the start to find out if the tRNS chunk consisted6631* entirely of opaque (255) and/or transparent (0) entries.6632*/6633if (tc->init == PNG_TC_INIT_FORMAT &&6634png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)6635check_tRNS_for_alpha(png_ptr);6636# endif /* READ_tRNS */6637cp.end = cp.start = list;6638cp.tend = cp.tstart = *tc;6639max_depth = cache_start_depth = PNG_TC_PIXEL_DEPTH(cp.tend);66406641while (*cp.end != NULL)6642{6643png_transformp tr = *cp.end;66446645/* The user transform cannot be cached. */6646if (tr->order >= PNG_TR_USER)6647break;66486649/* If caching is not on and this transform is after PNG_TR_START_CACHE6650* try to turn it on.6651*/6652if (tr->order > PNG_TR_START_CACHE && !cp.tend.caching)6653{6654cp.start = cp.end;6655cp.tstart = cp.tend;6656init_caching(png_ptr, &cp.tend);66576658if (cp.tend.caching)6659{6660cache_start_depth = max_depth;6661max_depth = PNG_TC_PIXEL_DEPTH(cp.tend);6662}6663}66646665/* If the 'palette' flag is set and the next transform has order6666* PNG_TR_ENCODING or later cache the results so far and continue with the6667* original palette data (cp.tstart).6668*/6669if (cp.tend.palette && tr->order >= PNG_TR_ENCODING)6670{6671handle_cache(png_ptr, &cp, max_depth);66726673/* The cache handling function must maintain cp.end; */6674affirm(tr == *cp.end);6675max_depth = PNG_TC_PIXEL_DEPTH(cp.tend);6676if (max_depth < cache_start_depth)6677max_depth = cache_start_depth;6678}66796680/* Now run the transform list entry: */6681if (tr->fn != NULL)6682{6683tr->fn(cp.end, &cp.tend);6684tr = *cp.end; /* in case something was inserted */6685}66866687if (tr->fn == NULL) /* delete this transform */6688png_remove_transform(png_ptr, cp.end);66896690else6691{6692/* Handle the initialization of the maximum pixel depth. */6693unsigned int tc_depth = PNG_TC_PIXEL_DEPTH(cp.tend);66946695if (tc_depth > max_depth)6696max_depth = tc_depth;66976698/* Advance to the next transform. */6699cp.end = &tr->next;6700}6701}67026703/* At the end if still caching record the cache information (this is common;6704* this is generally the case for an expanded palette.)6705*/6706if (cp.tend.caching)6707{6708png_transformp tr = *cp.end;6709handle_cache(png_ptr, &cp, max_depth);6710affirm(tr == *cp.end);6711max_depth = PNG_TC_PIXEL_DEPTH(cp.tend);6712if (max_depth < cache_start_depth)6713max_depth = cache_start_depth;6714}67156716/* At the end run the init on the user transform: */6717if (*cp.end != NULL)6718{6719png_transformp tr = *cp.end;6720affirm(tr->order == PNG_TR_USER);6721if (tr->fn != NULL)6722tr->fn(cp.end, &cp.tend);6723/* This cannot insert anything, so: */6724affirm(tr == *cp.end && tr->next == NULL);67256726if (tr->fn == NULL) /* delete this transform */6727png_remove_transform(png_ptr, cp.end);67286729else6730{6731unsigned int tc_depth = PNG_TC_PIXEL_DEPTH(cp.tend);67326733if (tc_depth > max_depth)6734max_depth = tc_depth;6735}6736}67376738/* And write the input transform control: */6739*tc = cp.tend;67406741return max_depth;6742}67436744/* Modify the info structure to reflect the transformations. The6745* info should be updated so a PNG file could be written with it,6746* assuming the transformations result in valid PNG data.6747*/6748void /* PRIVATE */6749png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)6750{6751png_debug(1, "in png_read_transform_info");67526753/* WARNING: this is very basic at present. It just updates the format6754* information. It should update the palette (and will eventually) as well6755* as invalidating chunks that the transforms break.6756*/6757# ifdef PNG_TRANSFORM_MECH_SUPPORTED6758info_ptr->format = png_ptr->row_format;6759info_ptr->bit_depth = png_ptr->row_bit_depth;6760# ifdef PNG_READ_GAMMA_SUPPORTED6761/* If an info struct is used with a different png_ptr in a call to6762* png_set_gAMA then the png_struct information won't be updated, this6763* doesn't matter on write, but don't zap the value in the info on read6764* unless it is known:6765*6766* TODO: review this whole mess.6767*/6768if (png_ptr->row_gamma > 0)6769info_ptr->colorspace.gamma = png_ptr->row_gamma;6770# endif67716772/* Invalidate chunks marked as invalid: */6773# ifdef PNG_READ_TRANSFORMS_SUPPORTED6774info_ptr->valid &= ~png_ptr->invalid_info;67756776/* If the palette or tRNS chunk was changed copy them over to the info6777* structure; this may actually re-validate the PLTE or tRNS chunks,6778* but only if png_ptr has a new version, otherwise the invalid_info6779* settings from above can still invalidate the chunk.6780*/6781if (png_ptr->palette_updated)6782{6783if (png_ptr->num_palette > 0)6784png_set_PLTE(png_ptr, info_ptr, png_ptr->palette,6785png_ptr->num_palette);67866787else6788{6789png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);6790info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_PLTE);6791}67926793# ifdef PNG_READ_tRNS6794/* If the output format is not a palette format the tRNS6795* information was a single color which is now invalid6796* (probably), otherwise the array of tRNS values must be6797* updated.6798*/6799if ((info_ptr->format & PNG_FORMAT_FLAG_COLORMAP) != 0)6800{6801if (png_ptr->num_trans > 0)6802png_set_tRNS(png_ptr, info_ptr, png_ptr->trans_alpha,6803png_ptr->num_trans, NULL/*trans color*/);68046805else6806{6807png_free_data(png_ptr, info_ptr, PNG_FREE_tRNS, 0);6808info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_tRNS);6809}6810}68116812else6813info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_tRNS);6814# endif /* READ_tRNS */6815}6816# endif /* READ_TRANSFORMS */6817# else /* !TRANSFORM_MECH */6818PNG_UNUSED(png_ptr)6819PNG_UNUSED(info_ptr)6820# endif /* !TRANSFORM_MECH */6821}6822#endif /* READ_TRANSFORMS */682368246825