/* pngtrans.c - transforms the data in a row (used by both readers and writers) * *Copyright(c)2018-2026CosminTruta *Copyright(c)1998-2002,2004,2006-2018GlennRanders-Pehrson *Copyright(c)1996-1997AndreasDilger *Copyright(c)1995-1996GuyEricSchalnat,Group42,Inc. * *Thiscodeisreleasedunderthelibpnglicense. *Forconditionsofdistributionanduse,seethedisclaimer *andlicenseinpng.h
*/
#ifdefined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) /* Add a filler byte on read, or remove a filler or alpha byte on write. *Thefillertypehaschangedinv0.95toallowfuture2-bytefillers *for48-bitinputdata,aswellastoavoidproblemswithsomecompilers *thatdon'tlikebytesasparameters.
*/ void PNGAPI
png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
{
png_debug(1, "in png_set_filler");
if (png_ptr == NULL) return;
/* In libpng 1.6 it is possible to determine whether this is a read or write *operationandthereforetodomorecheckinghereforavalidcall.
*/ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
{ # ifdef PNG_READ_FILLER_SUPPORTED /* On read png_set_filler is always valid, regardless of the base PNG *format,becauseothertransformationscangiveaformatwherethe *fillercodecanexecute(basicallyan8or16-bitcomponentRGBorG *format.) * *NOTE:usr_channelsisnotusedbythereadcode!(Thishasledto *confusioninthepast.)Thefillerisonlyusedinthereadcode.
*/
png_ptr->filler = (png_uint_16)filler; # else
png_app_error(png_ptr, "png_set_filler not supported on read");
PNG_UNUSED(filler) /* not used in the write case */ return; # endif
}
else/* write */
{ # ifdef PNG_WRITE_FILLER_SUPPORTED /* On write the usr_channels parameter must be set correctly at the *starttorecordthenumberofchannelsintheapp-supplieddata.
*/ switch (png_ptr->color_type)
{ case PNG_COLOR_TYPE_RGB:
png_ptr->usr_channels = 4; break;
case PNG_COLOR_TYPE_GRAY: if (png_ptr->bit_depth >= 8)
{
png_ptr->usr_channels = 2; break;
}
else
{ /* There simply isn't any code in libpng to strip out bits *frombyteswhenthecomponentsarelessthanabytein *size!
*/
png_app_error(png_ptr, "png_set_filler is invalid for" " low bit depth gray output"); return;
}
default:
png_app_error(png_ptr, "png_set_filler: inappropriate color type"); return;
} # else
png_app_error(png_ptr, "png_set_filler not supported on write"); return; # endif
}
/* Here on success - libpng supports the operation, set the transformation *andtheflagtosaywherethefillerchannelis.
*/
png_ptr->transformations |= PNG_FILLER;
if (filler_loc == PNG_FILLER_AFTER)
png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
else
png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
}
/* Added to libpng-1.2.7 */ void PNGAPI
png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
{
png_debug(1, "in png_set_add_alpha");
if (png_ptr == NULL) return;
png_set_filler(png_ptr, filler, filler_loc); /* The above may fail to do anything. */ if ((png_ptr->transformations & PNG_FILLER) != 0)
png_ptr->transformations |= PNG_ADD_ALPHA;
}
/* Invert monochrome grayscale data */ void/* PRIVATE */
png_do_invert(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_invert");
/* This test removed from libpng version 1.0.13 and 1.2.0: *if(row_info->bit_depth==1&&
*/ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
{
png_bytep rp = row;
size_t i;
size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i++)
{
*rp = (png_byte)(~(*rp));
rp++;
}
}
for (rp = row; rp < row_end; rp++)
*rp = table[*rp];
}
} #endif/* PACKSWAP || WRITE_PACKSWAP */
#ifdefined(PNG_WRITE_FILLER_SUPPORTED) || \ defined(PNG_READ_STRIP_ALPHA_SUPPORTED) /* Remove a channel - this used to be 'png_do_strip_filler' but it used a *somewhatweirdcombinationofflagstodeterminewhattodo.Allthecalls *topng_do_strip_fillerarechangedin1.5.2tocallthisinsteadwiththe *correctarguments. * *Theroutineisn'tgeneral-thechannelmustbethechannelatthestartor *end(notinthemiddle)ofeachpixel.
*/ void/* PRIVATE */
png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
{
png_bytep sp = row; /* source pointer */
png_bytep dp = row; /* destination pointer */
png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
png_debug(1, "in png_do_strip_channel");
/* At the start sp will point to the first byte to copy and dp to where *itiscopiedto.epalwayspointsjustbeyondtheendoftherow,so *theloopsimplycopies(channels-1)channelsuntilspreachesep. * *at_start:0--convertAG,XG,ARGB,XRGB,AAGG,XXGG,etc. *nonzero--convertGA,GX,RGBA,RGBX,GGAA,RRGGBBXX,etc.
*/
/* GA, GX, XG cases */ if (row_info->channels == 2)
{ if (row_info->bit_depth == 8)
{ if (at_start != 0) /* Skip initial filler */
++sp; else/* Skip initial channel and, for sp, the filler */
{
sp += 2; ++dp;
}
/* For a 1 pixel wide image there is nothing to do */ while (sp < ep)
{
*dp++ = *sp; sp += 2;
}
/* Finally fix the color type if it records an alpha channel */ if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
row_info->color_type = PNG_COLOR_TYPE_GRAY;
}
/* Finally fix the color type if it records an alpha channel */ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
row_info->color_type = PNG_COLOR_TYPE_RGB;
}
else return; /* The filler channel has gone already */
#ifdefined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) /* Swaps red and blue bytes within a pixel */ void/* PRIVATE */
png_do_bgr(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_bgr");
if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
{
png_uint_32 row_width = row_info->width; if (row_info->bit_depth == 8)
{ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
{
png_bytep rp;
png_uint_32 i;
for (i = 0, rp = row; i < row_width; i++, rp += 3)
{
png_byte save = *rp;
*rp = *(rp + 2);
*(rp + 2) = save;
}
}
for (i = 0, rp = row; i < row_width; i++, rp += 8)
{
png_byte save = *rp;
*rp = *(rp + 4);
*(rp + 4) = save;
save = *(rp + 1);
*(rp + 1) = *(rp + 5);
*(rp + 5) = save;
}
}
} #endif
}
} #endif/* READ_BGR || WRITE_BGR */
#ifdefined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) /* Added at libpng-1.5.10 */ void/* PRIVATE */
png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
{
png_debug(1, "in png_do_check_palette_indexes");
if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
{ /* Calculations moved outside switch in an attempt to stop different *compilerwarnings.'padding'isin*bits*withinthelastbyte,itis *an'int'becausepixel_depthbecomesan'int'intheexpressionbelow, *andthiscalculationisusedbecauseitavoidswarningsthatother *formsproducedoneitherGCCorMSVC.
*/ int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
switch (row_info->bit_depth)
{ case1:
{ /* in this case, all bytes must be 0 so we don't need *tounpackthepixelsexceptfortherightmostone.
*/ for (; rp > png_ptr->row_buf; rp--)
{ if ((*rp >> padding) != 0)
png_ptr->num_palette_max = 1;
padding = 0;
}
break;
}
case2:
{ for (; rp > png_ptr->row_buf; rp--)
{ int i = ((*rp >> padding) & 0x03);
if (i > png_ptr->num_palette_max)
png_ptr->num_palette_max = i;
i = (((*rp >> padding) >> 2) & 0x03);
if (i > png_ptr->num_palette_max)
png_ptr->num_palette_max = i;
i = (((*rp >> padding) >> 4) & 0x03);
if (i > png_ptr->num_palette_max)
png_ptr->num_palette_max = i;
i = (((*rp >> padding) >> 6) & 0x03);
if (i > png_ptr->num_palette_max)
png_ptr->num_palette_max = i;
padding = 0;
}
break;
}
case4:
{ for (; rp > png_ptr->row_buf; rp--)
{ int i = ((*rp >> padding) & 0x0f);
if (i > png_ptr->num_palette_max)
png_ptr->num_palette_max = i;
i = (((*rp >> padding) >> 4) & 0x0f);
if (i > png_ptr->num_palette_max)
png_ptr->num_palette_max = i;
padding = 0;
}
break;
}
case8:
{ for (; rp > png_ptr->row_buf; rp--)
{ if (*rp > png_ptr->num_palette_max)
png_ptr->num_palette_max = (int) *rp;
}
/* This function returns a pointer to the user_transform_ptr associated with *theusertransformfunctions.Theapplicationshouldfreeanymemory *associatedwiththispointerbeforepng_write_destroyandpng_read_destroy *arecalled.
*/ #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
png_voidp PNGAPI
png_get_user_transform_ptr(png_const_structrp png_ptr)
{ if (png_ptr == NULL) return NULL;
return png_ptr->user_transform_ptr;
} #endif
#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
png_uint_32 PNGAPI
png_get_current_row_number(png_const_structrp png_ptr)
{ /* See the comments in png.h - this is the sub-image row when reading an *interlacedimage.
*/ if (png_ptr != NULL) return png_ptr->row_number;
return PNG_UINT_32_MAX; /* help the app not to fail silently */
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.