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/pngwtran.c
Views: 1401
1/* pngwtran.c - transforms the data in a row for PNG writers2*3* Last changed in libpng 1.7.0 [(PENDING RELEASE)]4* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson5* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)6* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)7*8* This code is released under the libpng license.9* For conditions of distribution and use, see the disclaimer10* and license in png.h11*/1213#include "pngpriv.h"14#define PNG_SRC_FILE PNG_SRC_FILE_pngwtran1516#ifdef PNG_WRITE_PACK_SUPPORTED17/* Pack pixels into bytes. */18static void19png_do_write_pack(png_transformp *transform, png_transform_controlp tc)20{21png_alloc_size_t rowbytes = PNG_TC_ROWBYTES(*tc);22png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);23png_const_bytep ep = png_upcast(png_const_bytep, tc->sp) + rowbytes;24png_bytep dp = png_voidcast(png_bytep, tc->dp);2526png_debug(1, "in png_do_pack");2728# define png_ptr tc->png_ptr2930switch ((*transform)->args)31{32case 1:33{34unsigned int mask = 0x80, v = 0;3536while (sp < ep)37{38if (*sp++ != 0)39v |= mask;4041mask >>= 1;4243if (mask == 0)44{45mask = 0x80;46*dp++ = PNG_BYTE(v);47v = 0;48}49}5051if (mask != 0x80)52*dp++ = PNG_BYTE(v);53break;54}5556case 2:57{58unsigned int shift = 8, v = 0;5960while (sp < ep)61{62shift -= 2;63v |= (*sp++ & 0x3) << shift;6465if (shift == 0)66{67shift = 8;68*dp++ = PNG_BYTE(v);69v = 0;70}71}7273if (shift != 8)74*dp++ = PNG_BYTE(v);75break;76}7778case 4:79{80unsigned int shift = 8, v = 0;8182while (sp < ep)83{84shift -= 4;85v |= ((*sp++ & 0xf) << shift);8687if (shift == 0)88{89shift = 8;90*dp++ = PNG_BYTE(v);91v = 0;92}93}9495if (shift != 8)96*dp++ = PNG_BYTE(v);97break;98}99100default:101impossible("bit depth");102}103104if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0 &&105--(tc->range) == 0)106tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_RANGE);107108tc->bit_depth = (*transform)->args;109tc->sp = tc->dp;110# undef png_ptr111}112113void /* PRIVATE */114png_init_write_pack(png_transformp *transform, png_transform_controlp tc)115{116# define png_ptr tc->png_ptr117debug(tc->init);118# undef png_ptr119120/* The init routine is called *forward* so the transform control we get has121* the required bit depth and the transform routine will increase it to 8122* bits per channel. The code doesn't really care how many channels there123* are, but the only way to get a channel depth of less than 8 is to have124* just one channel.125*/126if (tc->bit_depth < 8) /* else no packing/unpacking */127{128if (tc->init == PNG_TC_INIT_FINAL)129{130(*transform)->fn = png_do_write_pack;131/* Record this for the backwards run: */132(*transform)->args = tc->bit_depth & 0xf;133}134135if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0)136{137tc->range++;138tc->format |= PNG_FORMAT_FLAG_RANGE; /* forwards: backwards cancels */139}140141tc->bit_depth = 8;142}143144else /* the transform is not applicable */145(*transform)->fn = NULL;146}147#endif /* WRITE_PACK */148149150