コード例 #1
0
ファイル: ut_png.cpp プロジェクト: hfiguiere/abiword
static void _png_read(png_structp png_ptr, png_bytep data, png_size_t length)
{
	struct _bb* p = static_cast<struct _bb*>(png_get_io_ptr(png_ptr));
	const UT_Byte* pBytes = p->pBB->getPointer(0);

	// make sure that we don't read outside of pBytes
	if (p->iCurPos >= p->pBB->getLength() - length) {
		UT_WARNINGMSG(("PNG: Reading past buffer bounds. cur = %u, buflen = %u, length = %lu\n",
					   p->iCurPos, p->pBB->getLength(), length));
		length = p->pBB->getLength() - p->iCurPos;
		if (length == 0) {
			UT_WARNINGMSG(("PNG: Truncating to ZERO length.\n"));
			png_error(png_ptr, "Premature end of buffer");
			return;
		} else {
			UT_WARNINGMSG(("PNG: Truncating to %lu.\n", length));
		}
	}
	memcpy(data, pBytes + p->iCurPos, length);
	p->iCurPos += length;
}
コード例 #2
0
ファイル: output_common.c プロジェクト: baspijhor/caer
static void caerLibPNGWriteBuffer(png_structp png_ptr, png_bytep data, png_size_t length) {
	struct mem_encode *p = (struct mem_encode *) png_get_io_ptr(png_ptr);
	size_t nsize = p->size + length;

	// Allocate or grow buffer as needed.
	if (p->buffer) {
		p->buffer = realloc(p->buffer, nsize);
	}
	else {
		p->buffer = malloc(nsize);
	}

	if (p->buffer == NULL) {
		png_error(png_ptr, "Write Buffer Error");
		return;
	}

	// Copy the new bytes to the end of the buffer.
	memcpy(p->buffer + p->size, data, length);
	p->size += length;
}
コード例 #3
0
ファイル: PngReader.cpp プロジェクト: PACSinTERRA/orthanc
  void PngReader::PngRabi::MemoryCallback(png_structp png_ptr, 
                                          png_bytep outBytes, 
                                          png_size_t byteCountToRead)
  {
    MemoryBuffer* from = reinterpret_cast<MemoryBuffer*>(png_get_io_ptr(png_ptr));

    if (!from->ok_)
    {
      return;
    }

    if (from->pos_ + byteCountToRead > from->size_)
    {
      from->ok_ = false;
      return;
    }

    memcpy(outBytes, from->buffer_ + from->pos_, byteCountToRead);

    from->pos_ += byteCountToRead;
  }
コード例 #4
0
ファイル: gstpngdec.c プロジェクト: DylanZA/gst-plugins-good
static void
user_end_callback (png_structp png_ptr, png_infop info)
{
  GstPngDec *pngdec = NULL;

  pngdec = GST_PNGDEC (png_get_io_ptr (png_ptr));

  GST_LOG_OBJECT (pngdec, "and we are done reading this image");

  if (!pngdec->current_frame->output_buffer)
    return;

  gst_buffer_unmap (pngdec->current_frame->input_buffer,
      &pngdec->current_frame_map);

  pngdec->ret =
      gst_video_decoder_finish_frame (GST_VIDEO_DECODER (pngdec),
      pngdec->current_frame);

  pngdec->image_ready = TRUE;
}
コード例 #5
0
ファイル: read_png.c プロジェクト: rkrug/grass-ci
static void read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
  png_size_t check;
  FILE *fp;

  if (png_ptr == NULL )
    return;

  fp = (FILE *) png_get_io_ptr(png_ptr);

  if ( fp == NULL )
    return;

  /* fread() returns 0 on error, so it is OK to store this in a png_size_t
   * instead of an int, which is what fread() actually returns.
   */
  check = fread(data, 1, length, fp);

  if (check != length)
    G_fatal_error(_("Unable to read PNG"));
}
コード例 #6
0
ファイル: gstpngdec.c プロジェクト: ChinnaSuhas/ossbuild
static void
user_info_callback (png_structp png_ptr, png_infop info)
{
  GstPngDec *pngdec = NULL;
  GstFlowReturn ret = GST_FLOW_OK;
  size_t buffer_size;
  GstBuffer *buffer = NULL;

  pngdec = GST_PNGDEC (png_get_io_ptr (png_ptr));

  GST_LOG ("info ready");

  /* Generate the caps and configure */
  ret = gst_pngdec_caps_create_and_set (pngdec);
  if (ret != GST_FLOW_OK) {
    goto beach;
  }

  /* Allocate output buffer */
  pngdec->rowbytes = png_get_rowbytes (pngdec->png, pngdec->info);
  if (pngdec->rowbytes > (G_MAXUINT32 - 3)
      || pngdec->height > G_MAXUINT32 / pngdec->rowbytes) {
    ret = GST_FLOW_ERROR;
    goto beach;
  }
  pngdec->rowbytes = GST_ROUND_UP_4 (pngdec->rowbytes);
  buffer_size = pngdec->height * pngdec->rowbytes;

  ret =
      gst_pad_alloc_buffer_and_set_caps (pngdec->srcpad, GST_BUFFER_OFFSET_NONE,
      buffer_size, GST_PAD_CAPS (pngdec->srcpad), &buffer);
  if (ret != GST_FLOW_OK) {
    goto beach;
  }

  pngdec->buffer_out = buffer;

beach:
  pngdec->ret = ret;
}
コード例 #7
0
/*
 * Chunk handler
 */
static void opng_handle_chunk(png_structp png_ptr, png_bytep chunk_type)
{
    if (opng_is_image_chunk(chunk_type))
        return;
    struct opng_codec_context * context = (struct opng_codec_context *)png_get_io_ptr(png_ptr);
    struct opng_encoding_stats * stats = context->stats;

    /* Bypass the chunks that are intended to be stripped. */
    if (opng_transform_query_strip_chunk(context->transformer, chunk_type))
    {
        char debug_chunk_name[5];
        memcpy(debug_chunk_name, chunk_type, 4);
        debug_chunk_name[4] = (char)0;
        if (opng_is_apng_chunk(chunk_type))
        {
            /*printf("Snipping: %s\n", debug_chunk_name);*/
            stats->flags |= OPNG_HAS_SNIPPED_IMAGES;
        }
        else
        {
            /*printf("Stripping: %s\n", debug_chunk_name);*/
            stats->flags |= OPNG_HAS_STRIPPED_METADATA;
        }
        opng_set_keep_unknown_chunk(png_ptr, PNG_HANDLE_CHUNK_NEVER, chunk_type);
        return;
    }

    /* Let libpng handle bKGD, hIST and sBIT. */
    if (memcmp(chunk_type, opng_sig_bKGD, 4) == 0 ||
            memcmp(chunk_type, opng_sig_hIST, 4) == 0 ||
            memcmp(chunk_type, opng_sig_sBIT, 4) == 0)
        return;

    /* Everything else is handled as unknown by libpng. */
    if (memcmp(chunk_type, opng_sig_dSIG, 4) == 0)
        stats->flags |= OPNG_HAS_DIGITAL_SIGNATURE;
    else if (memcmp(chunk_type, opng_sig_fdAT, 4) == 0)
        stats->flags |= OPNG_HAS_MULTIPLE_IMAGES;
    opng_set_keep_unknown_chunk(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, chunk_type);
}
コード例 #8
0
ファイル: swf_png.c プロジェクト: gitpan/SWFEditor
void
png_data_write_func(png_structp png_ptr, png_bytep buf, png_size_t size) {
    my_png_buffer *png_buff = (my_png_buffer *)png_get_io_ptr(png_ptr);
    unsigned long new_data_len;
    unsigned char *tmp;
    if (png_buff->data_offset + size > png_buff->data_len) {
        new_data_len = 2 * png_buff->data_len;
        if (png_buff->data_offset + size > new_data_len) {
            new_data_len = png_buff->data_offset + size;
        }
        tmp = realloc(png_buff->data, new_data_len);
        if (tmp == NULL) {
            fprintf(stderr, "png_data_write_func: can't realloc: new_data_len(%lu), data_len(%lu)\n",
                    new_data_len, png_buff->data_len);
            png_error(png_ptr,"png_data_write_func failed");
        }
        png_buff->data = tmp;
        png_buff->data_len = new_data_len;
    }
    memcpy(png_buff->data + png_buff->data_offset, buf, size);
    png_buff->data_offset += size;
}
コード例 #9
0
ファイル: pngwrapper.cpp プロジェクト: maarten990/bsc-pga
void loadPNGEx_user_read_data(png_structp png_ptr,
							  png_bytep data, png_size_t length) {
	loadPNGExData *lPEd = (loadPNGExData *)png_get_io_ptr(png_ptr);

	// check requested length
	if ((int)length > lPEd->bufLength - lPEd->bufPos) {
		cprintf("loadPNGEx_user_read_data(): too much data requested by libpng, padding with 0\n");

		memset(data + lPEd->bufLength - lPEd->bufPos, 0, length - (lPEd->bufLength - lPEd->bufPos));
		length = lPEd->bufLength - lPEd->bufPos;
	}

	// copy data
	memcpy(data, lPEd->buf + lPEd->bufPos, length);

	// update structure
	lPEd->bufPos += (int)length;

	//return length;

	return;
}
コード例 #10
0
ファイル: png-helper.c プロジェクト: fallrisk/led_drapes
void tarpng_read_data(png_structp read_ptr, png_bytep data, png_size_t length)
{
	/* Get the animation archive. */
	struct archive *animarc;
	animarc = (struct archive *)png_get_io_ptr(read_ptr);
	/* printf("%d bytes requested\n", length); */
	int res;
	res = archive_read_data(animarc, data, length);
	/* If the result is zero then no more data. If the result is FATAL, WARN,
	 * or RETRY there was a problem. If the value is > 1 then it wrote that
	 * many bytes.
	 */
	if (res == 0) {
		printf("EOF\n");	
	} else if (res == ARCHIVE_FATAL || res == ARCHIVE_WARN || res == ARCHIVE_RETRY) {
		png_error(read_ptr, "Read Error!\n");
		printf("Read error!\n");
		/* set error and end */
	} else if ( res > 1) {
		/* printf("Read %d bytes.\n",res); */
	}
}
コード例 #11
0
ファイル: png_encoder.cpp プロジェクト: dahalecp/node-png
void
PngEncoder::png_chunk_producer(png_structp png_ptr, png_bytep data, png_size_t length)
{
    PngEncoder *p = (PngEncoder *)png_get_io_ptr(png_ptr);

    if (!p->png) {
        p->png = (char *)malloc(sizeof(p->png)*41); // from tests pngs are at least 41 bytes
        if (!p->png)
            throw "malloc failed in node-png (PngEncoder::png_chunk_producer)";
        p->mem_len = 41;
    }

    if (p->png_len + length > p->mem_len) {
        char *new_png = (char *)realloc(p->png, sizeof(char)*p->png_len + length);
        if (!new_png)
            throw "realloc failed in node-png (PngEncoder::png_chunk_producer).";
        p->png = new_png;
        p->mem_len += length;
    }
    memcpy(p->png + p->png_len, data, length);
    p->png_len += length;
}
コード例 #12
0
ファイル: png.c プロジェクト: ender672/axon
static VALUE
write_png2(VALUE *args)
{
    struct io_write *data;
    png_structp png_ptr = (png_structp)args[0];
    png_infop info_ptr = (png_infop)args[1];
    VALUE scanline, image_in = args[2];
    size_t i;

    write_configure(image_in, png_ptr, info_ptr);
    png_write_info(png_ptr, info_ptr);

    for (i = 0; i < png_get_image_height(png_ptr, info_ptr); i++) {
	scanline = rb_funcall(image_in, id_gets, 0);
	write_scanline(scanline, png_ptr, info_ptr);
    }
    png_write_end(png_ptr, info_ptr);

    data = (struct io_write *)png_get_io_ptr(png_ptr);

    return INT2FIX(data->total);
}
コード例 #13
0
ファイル: gstpngdec.c プロジェクト: ChinnaSuhas/ossbuild
static void
user_endrow_callback (png_structp png_ptr, png_bytep new_row,
    png_uint_32 row_num, int pass)
{
  GstPngDec *pngdec = NULL;

  pngdec = GST_PNGDEC (png_get_io_ptr (png_ptr));

  /* FIXME: implement interlaced pictures */

  /* If buffer_out doesn't exist, it means buffer_alloc failed, which 
   * will already have set the return code */
  if (GST_IS_BUFFER (pngdec->buffer_out)) {
    size_t offset = row_num * pngdec->rowbytes;

    GST_LOG ("got row %u, copying in buffer %p at offset %" G_GSIZE_FORMAT,
        (guint) row_num, pngdec->buffer_out, offset);
    memcpy (GST_BUFFER_DATA (pngdec->buffer_out) + offset, new_row,
        pngdec->rowbytes);
    pngdec->ret = GST_FLOW_OK;
  }
}
コード例 #14
0
ファイル: qpnghandler.cpp プロジェクト: AlekSi/phantomjs
static
void CALLBACK_CALL_TYPE iod_read_fn(png_structp png_ptr, png_bytep data, png_size_t length)
{
    QPngHandlerPrivate *d = (QPngHandlerPrivate *)png_get_io_ptr(png_ptr);
    QIODevice *in = d->q->device();

    if (d->state == QPngHandlerPrivate::ReadingEnd && !in->isSequential() && (in->size() - in->pos()) < 4 && length == 4) {
        // Workaround for certain malformed PNGs that lack the final crc bytes
        uchar endcrc[4] = { 0xae, 0x42, 0x60, 0x82 };
        qMemCopy(data, endcrc, 4);
        in->seek(in->size());
        return;
    }

    while (length) {
        int nr = in->read((char*)data, length);
        if (nr <= 0) {
            png_error(png_ptr, "Read Error");
            return;
        }
        length -= nr;
    }
}
コード例 #15
0
/* libpng calls this (at read_png_data's request)
* to copy data from the in-RAM PNG into our bitmap */
void read_cb (png_structp png_ptr, png_bytep outBytes, png_size_t byteCountToRead) {
	struct bufdata * bd = png_get_io_ptr(png_ptr);

	//pthread_mutex_lock(&lock_read_cb);
	if (bd == NULL)
		abort_("[read_png_file/read_cb] invalid memory passed to png reader");
	if (bd->pos + byteCountToRead >= bd->len)
	{
#ifdef _DEBUG_1_
	printf("\nError (read_cb): bd->pos: %d, byteCountToRead: %d, bd->len: %d\n", bd->pos, byteCountToRead, bd->len);
	fflush(stdout);
#endif
		abort_("[read_png_file/read_cb] attempting to read beyond end of buffer");
	}
#ifdef _DEBUG_1_
	//printf("\read_cb: bd->pos: %d, byteCountToRead: %d, bd->len: %d\n", bd->pos, byteCountToRead, bd->len);
	//fflush(stdout);
#endif

	memcpy(outBytes, bd->buf+bd->pos, byteCountToRead);
	bd->pos += byteCountToRead;
	//pthread_mutex_unlock(&lock_read_cb);
}
コード例 #16
0
ファイル: pngtest.c プロジェクト: 52nlp/LabelMeAnnotationTool
static void
pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
   png_size_t check;
   png_byte *n_data;
   png_FILE_p io_ptr;

   /* Check if data really is near. If so, use usual code. */
   n_data = (png_byte *)CVT_PTR_NOCHECK(data);
   io_ptr = (png_FILE_p)CVT_PTR(png_get_io_ptr(png_ptr));
   if ((png_bytep)n_data == data)
   {
      check = fread(n_data, 1, length, io_ptr);
   }
   else
   {
      png_byte buf[NEAR_BUF_SIZE];
      png_size_t read, remaining, err;
      check = 0;
      remaining = length;
      do
      {
         read = MIN(NEAR_BUF_SIZE, remaining);
         err = fread(buf, 1, 1, io_ptr);
         png_memcpy(data, buf, read); /* Copy far buffer to near buffer */
         if (err != read)
            break;
         else
            check += err;
         data += read;
         remaining -= read;
      }
      while (remaining != 0);
   }
   if (check != length)
      png_error(png_ptr, "read Error");
}
コード例 #17
0
ファイル: png.c プロジェクト: ender672/axon
void
read_data_fn(png_structp png_ptr, png_bytep data, png_size_t length)
{
    VALUE io, str;
    size_t read_len;

    if (png_ptr == NULL)
	return;

    io = (VALUE)png_get_io_ptr(png_ptr);
    str = rb_funcall(io, id_read, 1, INT2FIX(length));

    if (NIL_P(str))
	rb_raise(rb_eRuntimeError, "Read Error. Reader returned nil.");

    StringValue(str);
    read_len = RSTRING_LEN(str);

    if (read_len != length)
	rb_raise(rb_eRuntimeError, "Read Error. Read %d instead of %d bytes.",
		 (int)read_len, (int)length);

    memcpy(data, RSTRING_PTR(str), length);
}
コード例 #18
0
ファイル: cellPngDec.cpp プロジェクト: DreadIsBack/rpcs3
// Custom read function for libpng, so we could decode images from a buffer
void pngDecReadBuffer(png_structp png_ptr, png_bytep out, png_size_t length)
{
	// Get the IO pointer
	png_voidp io_ptr = png_get_io_ptr(png_ptr);

	// Check if obtaining of the IO pointer failed
	if (!io_ptr)
	{
		cellPngDec.error("Failed to obtain the io_ptr failed.");
		return;
	}

	// Cast the IO pointer to our custom structure
	PngBuffer& buffer = *(PngBuffer*)io_ptr;

	// Read froma  file or a buffer
	if (buffer.file)
	{
		// Get the file
		auto file = idm::get<lv2_file_t>(buffer.fd);

		// Read the data
		file->file.read(out, length);
	}
	else
	{
		// Get the current data pointer, including the current cursor position
		void* data = static_cast<u8*>(buffer.data.get_ptr()) + buffer.cursor;

		// Copy the length of the current data pointer to the output
		memcpy(out, data, length);

		// Increment the cursor for the next time
		buffer.cursor += length;
	}
}
コード例 #19
0
ファイル: gstpngenc.c プロジェクト: an146/gst-plugins-good
static void
user_write_data (png_structp png_ptr, png_bytep data, png_uint_32 length)
{
    GstPngEnc *pngenc;
    GstMapInfo map;

    pngenc = (GstPngEnc *) png_get_io_ptr (png_ptr);

    gst_buffer_map (pngenc->buffer_out, &map, GST_MAP_WRITE);
    if (pngenc->written + length >= map.size) {
        gst_buffer_unmap (pngenc->buffer_out, &map);
        GST_ERROR_OBJECT (pngenc, "output buffer bigger than the input buffer!?");
        png_error (png_ptr, "output buffer bigger than the input buffer!?");

        /* never reached */
        return;
    }

    GST_DEBUG_OBJECT (pngenc, "writing %u bytes", (guint) length);

    memcpy (map.data + pngenc->written, data, length);
    gst_buffer_unmap (pngenc->buffer_out, &map);
    pngenc->written += length;
}
コード例 #20
0
ファイル: PNGCodec.cpp プロジェクト: Frizlee/ModelViewer
void PNGReadCallback(png_structp PNGPtr, png_bytep outBytes,
	png_size_t byteCountToRead)
{
	PNGVectorStream *stream = reinterpret_cast<PNGVectorStream*>(png_get_io_ptr(PNGPtr));

	if (stream == nullptr)
	{
		// TODO: Error handling.
		outBytes = nullptr;
		return;
	}

	if (stream->offset + byteCountToRead > stream->vec->size())
	{
		// TODO: Error handling.
		stream->offset = stream->vec->size();
		outBytes = nullptr;
		return;
	}

	memcpy(outBytes, &(*stream->vec)[stream->offset], byteCountToRead);
	// outBytes = &(*stream->vec)[stream->offset];
	stream->offset += byteCountToRead;
}
コード例 #21
0
ファイル: GameWindow.cpp プロジェクト: aap/openrw
void GameWindow::captureToFile(const std::string& path, GameRenderer* renderer)
{
	Logger log;

	std::ofstream file(path);
	if (!file.is_open()) {
		log.error("Game", "Could not open screenshot file!");
		return;
	}

	png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
		nullptr, nullptr, nullptr);

	png_infop info_ptr = png_create_info_struct(png_ptr);

	png_set_write_fn(png_ptr, &file, {
		[](png_structp png_ptr, png_bytep data, png_size_t length) {
			reinterpret_cast<std::ofstream*>(png_get_io_ptr(png_ptr))->
				write(reinterpret_cast<char*>(data), length);
		} }, { [](png_structp) { } } );

	auto size = getSize();
	png_set_IHDR(png_ptr, info_ptr, size.x, size.y, 8, PNG_COLOR_TYPE_RGB,
		PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

	png_write_info(png_ptr, info_ptr);

	unsigned char* buffer = renderer->getRenderer()->readPixels(size);
	for (int y = size.y-1; y >= 0; y--)
		png_write_row(png_ptr, &buffer[y * size.x * 3]);

	png_write_end(png_ptr, nullptr);
	png_destroy_write_struct(&png_ptr, &info_ptr);

	delete[] buffer;
}
コード例 #22
0
ファイル: main.c プロジェクト: spinclick/pnglitch
int begin(char* base_file_name, unsigned char *png_buf, long long png_length) {

  MY_PNG_READ_OFFSET = 0;
  PNG_LENGTH = png_length; 
  ENTIRE_PNG_BUF = png_buf;

  if (png_sig_cmp(ENTIRE_PNG_BUF, 0, 8) != 0) {
    error(-1, "png_sig_cmp", E_INVALID);
    return -1;
  }

  DEBUG_PRINT(("Initial png size is %lld bytes\n", PNG_LENGTH));

  my_png_meta *pm = calloc(1, sizeof(my_png_meta));
  my_init_libpng(pm);

  //If libpng errors, we end up here
  if (setjmp(png_jmpbuf(pm->read_ptr))) {
    DEBUG_PRINT(("libpng called setjmp!\n"));
    my_deinit_libpng(pm);
    free(ENTIRE_PNG_BUF);
    error(-1, "libpng", "libpng encountered an error\n");
    return -1;
  }

  //Normally a file, but instead make it our buffer
  void *read_io_ptr = png_get_io_ptr(pm->read_ptr);
  png_set_read_fn(pm->read_ptr, read_io_ptr, my_png_read_fn);

  //Transform all PNG image types to RGB
  int transforms = 
    PNG_TRANSFORM_GRAY_TO_RGB |
    PNG_TRANSFORM_STRIP_ALPHA | 
    PNG_TRANSFORM_EXPAND;

  png_read_png(pm->read_ptr, pm->info_ptr, transforms, NULL);

  //Now that it was read and transformed, its size will differ
  PNG_LENGTH = 0; 

  //Lets collect our metadata
  struct ihdr_infos_s ihdr_infos;
  ihdr_infos.bit_depth        = png_get_bit_depth(pm->read_ptr, pm->info_ptr);
  ihdr_infos.color_type       = png_get_color_type(pm->read_ptr, pm->info_ptr);
  ihdr_infos.filter_method    = png_get_filter_type(pm->read_ptr, pm->info_ptr);
  ihdr_infos.compression_type = png_get_compression_type(pm->read_ptr, pm->info_ptr);
  ihdr_infos.interlace_type   = png_get_interlace_type(pm->read_ptr, pm->info_ptr);
  ihdr_infos.height           = png_get_image_height(pm->read_ptr, pm->info_ptr);
  ihdr_infos.width            = png_get_image_width(pm->read_ptr, pm->info_ptr);

  if (ihdr_infos.color_type != 2) {
    DEBUG_PRINT((E_INVALID));
    free(ENTIRE_PNG_BUF);
    my_deinit_libpng(pm);
    DEBUG_PRINT(("Looks like libpng could not correctly convert to RGB\n"));
    return -1;
  }

  //Just in case we want to enable alpha, etc
  switch(ihdr_infos.color_type) {
    case 0:  //greyscale
    case 3:  //indexed
      ihdr_infos.bytes_per_pixel = 1;
      break;
    case 4: ihdr_infos.bytes_per_pixel = 2; break; //greyscale w/ alpha 
    case 2: ihdr_infos.bytes_per_pixel = 3; break; //Truecolour (RGB)
    case 6: ihdr_infos.bytes_per_pixel = 4; break; //Truecolour w/ alpha
    default: error_fatal(1, "ihdr_infos", "Unknown image type"); //should never happen
  }

  ihdr_infos.scanline_len = (ihdr_infos.bytes_per_pixel * ihdr_infos.width) + 1;

  DEBUG_PRINT(("HEIGHT: %u\n", ihdr_infos.height));
  DEBUG_PRINT(("WIDTH: %u\n", ihdr_infos.width));
  DEBUG_PRINT(("BIT_DEPTH: %u\n", ihdr_infos.bit_depth));

  // Don't compress, since we are merely copying it to memory,
  // we will be decompressing it again anyway
  png_set_compression_level(pm->write_ptr, Z_NO_COMPRESSION);

  void *write_io_ptr = png_get_io_ptr(pm->write_ptr);
  png_set_write_fn(pm->write_ptr, write_io_ptr, my_png_write_fn, my_png_dummy_flush);

  //Make sure we use all filters
  png_set_filter(pm->write_ptr, 0,
      PNG_FILTER_NONE  | PNG_FILTER_VALUE_NONE |
      PNG_FILTER_SUB   | PNG_FILTER_VALUE_SUB  |
      PNG_FILTER_UP    | PNG_FILTER_VALUE_UP   |
      PNG_FILTER_AVG   | PNG_FILTER_VALUE_AVG  |
      PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH);

  //Set our comment
  struct png_text_struct comment_struct;

  comment_struct.compression = -1;
  comment_struct.key = " Glitched by pnglitch.xyz ";
  comment_struct.text = NULL;
  comment_struct.text_length = 0;
  
  png_set_text(pm->write_ptr, pm->info_ptr, &comment_struct, 1);

  //Buffer is Written using callback my_png_write_fn to buffer
  //ENTIRE_PNG_BUF. PNG_LENGTH will be updated automatically by it
  png_write_png(pm->write_ptr, pm->info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

  my_deinit_libpng(pm);

  DEBUG_PRINT(("libpng output buf is %lld bytes\n", PNG_LENGTH));

  //Now that libpng has converted the image
  //and we have it in a buffer, we process it by hand with zlib
  struct z_stream_s inflate_stream;
  my_init_zlib(&inflate_stream);
  inflateInit(&inflate_stream);

  //Pointer to keep track of where we are
  unsigned char *pngp = ENTIRE_PNG_BUF;

  //Skip PNG Signature
  pngp += 8; 

  //Get Header
  unsigned char ihdr_bytes_buf[4+4+13+4]; // size + label + content + crc
  buf_read(ihdr_bytes_buf, &pngp, 4+4+13+4);

  //When we run into non-idat chunks, we will want to preserve them.
  //The spec says there's no chunk that needs to go after IDAT,
  //so we can simply concatenate all of these chunks into a buffer
  //then write them all at once after the IHDR
  
  //ancillary chunks, eg comments
  unsigned char *ancil_chunks_buf = calloc(1,1);
  long long ancil_chunks_len = 0;

  unsigned char *unzip_idats_buf = calloc(1, 1);
  long unzip_buf_len = 1;
  long unzip_buf_offset = 0;

  long long zipped_idats_len = 0; //Length of all idats as we read them

  unsigned long accum_png_len = 8 + (4+4+13+4);

  int chunk_count = 0;

  printf("Uncompressing image data...\n");
  while (1) {
    unsigned char chunk_label[4];
    unsigned char chunk_len_buf[4];

    buf_read(chunk_len_buf, &pngp, 4);

    //first 4 bytes are the length of data section
    long chunk_len = four_bytes_to_int(chunk_len_buf);

    accum_png_len += chunk_len + 4 + 4 + 4; // plus len, crc, label
    DEBUG_PRINT(("at %lu --> %lld\n", accum_png_len, PNG_LENGTH));

    //leave at end of buffer
    if (accum_png_len >= PNG_LENGTH)
      break;

    //read the chunk label (name of this header)
    buf_read(chunk_label, &pngp, 4);

    DEBUG_PRINT(("Reading chunk %d with label '%c%c%c%c', size %ld\n",
          chunk_count, chunk_label[0], chunk_label[1], chunk_label[2],
          chunk_label[3], chunk_len));

    chunk_count += 1;

    if (memcmp(chunk_label, "IDAT", 4) == 0) {

      zipped_idats_len += chunk_len;

      //read the chunk's data section
      unsigned char *raw_chunk_buf = calloc(chunk_len, 1);
      buf_read(raw_chunk_buf, &pngp, chunk_len);

      //Tell inflate to uncompress it
      inflate_stream.next_in = raw_chunk_buf; 
      inflate_stream.avail_in = chunk_len; 

      //Now uncompress it (resizes buffer automatically)
      unsigned char *check_uncompress = uncompress_buffer(&inflate_stream, 
          unzip_idats_buf, &unzip_buf_len, &unzip_buf_offset);

      //Stop if error
      if (check_uncompress == NULL) {
        DEBUG_PRINT((E_GLITCH));
        free(ancil_chunks_buf);
        free(raw_chunk_buf);
        free(unzip_idats_buf);
        free(ENTIRE_PNG_BUF);
        return -1;
      }

      //Moving on
      unzip_idats_buf = check_uncompress;
      free(raw_chunk_buf);
      pngp += 4; // skip CRC

    } else { //This is not an idat

      ancil_chunks_buf = realloc(ancil_chunks_buf, 
          ancil_chunks_len + 4 + 4 + chunk_len + 4); //make room for new data

      //append length and label bytes
      append_bytes(ancil_chunks_buf, chunk_len_buf, &ancil_chunks_len, 4);
      append_bytes(ancil_chunks_buf, chunk_label, &ancil_chunks_len, 4);

      //append chunk data
      unsigned char *raw_chunk_buf = calloc(chunk_len, 1);
      buf_read(raw_chunk_buf, &pngp, chunk_len);
      append_bytes(ancil_chunks_buf, raw_chunk_buf, &ancil_chunks_len, chunk_len );

      //append chunk crc
      unsigned char chunk_crc_buf[4];
      buf_read(chunk_crc_buf, &pngp, 4);
      append_bytes(ancil_chunks_buf, chunk_crc_buf, &ancil_chunks_len, 4);

      free(raw_chunk_buf);

      DEBUG_PRINT(("ancillary chunks length: %lld\n", ancil_chunks_len));

    }
  }

  //buf contains all idats uncompressed, concatenated
  unsigned long unzipped_idats_len = inflate_stream.total_out; 
  unzip_idats_buf = realloc(unzip_idats_buf, unzipped_idats_len);

  //we already have ancillary chunks and idats, don't need the original
  free(ENTIRE_PNG_BUF);
  inflateEnd(&inflate_stream);

  printf("Uncompressed %lld bytes to %ld bytes\n", zipped_idats_len, unzipped_idats_len);

  printf("Glitching image data...\n");

  for (int g=0;g<NUM_OUTPUT_FILES;g++) {

    //do glitches
    switch(g) {
      case 5:
        glitch_random(unzip_idats_buf, unzipped_idats_len,
            ihdr_infos.scanline_len, 0.0005);
        break;
      case 6:
        glitch_random_filter(unzip_idats_buf, unzipped_idats_len,
            ihdr_infos.scanline_len);
        break;
      default:
        glitch_filter(unzip_idats_buf, unzipped_idats_len,
            ihdr_infos.scanline_len, g);
    }

    //recompress so we can write them to file
    long long glitched_idats_len = 0;
    unsigned char *glitched_idats = zip_idats(unzip_idats_buf,
        unzipped_idats_len, &glitched_idats_len);

    if (glitched_idats == NULL) {
      DEBUG_PRINT((E_GLITCH));
      free (unzip_idats_buf);
      free (ancil_chunks_buf);
      return -1;
    }

    char path[MAX_PATH_LENGTH];
    bzero(path, MAX_PATH_LENGTH);

    snprintf(path, MAX_PATH_LENGTH, "%s%s%s-%d.png", OUTPUT_DIRECTORY, DIR_SEP,
        base_file_name, g);

    DEBUG_PRINT(("Output file name is %s\n", path));

    FILE *outfp = fopen(path, "wb");

    write_glitched_image(glitched_idats, glitched_idats_len, ihdr_bytes_buf,
        ancil_chunks_buf, ancil_chunks_len, outfp);

    printf("%s\n", path);
    fflush(stdout);

    fclose(outfp);
    free(glitched_idats);
  }

  free(ancil_chunks_buf);
  free(unzip_idats_buf);
  return 0;
}
コード例 #23
0
/* read_data:
 *  Custom read function to use Allegro packfile routines,
 *  rather than C streams (so we can read from datafiles!)
 */
static void read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
{
    PACKFILE *f = (PACKFILE *)png_get_io_ptr(png_ptr);
    if ((png_uint_32)pack_fread(data, length, f) != length)
	png_error(png_ptr, "read error (loadpng calling pack_fread)");
}
コード例 #24
0
// write libpng output to PNG file
static void io_write(png_struct* png_ptr, u8* data, png_size_t length)
{
	DynArray* da = (DynArray*)png_get_io_ptr(png_ptr);
	if(da_append(da, data, length) != 0)
		png_error(png_ptr, "io_write failed");
}
コード例 #25
0
 static void write( png_structp png_ptr, png_bytep data, png_size_t length)
 {
     QAnimationWriterMNG* that = (QAnimationWriterMNG*)png_get_io_ptr(png_ptr);
     /*uint nw =*/ that->dev->writeBlock((const char*)data,length);
 }
コード例 #26
0
// Note: Calls req.Respond().  Other data can be added afterward.
static bool StreamBufferToDataURI(DebuggerRequest &req, const GPUDebugBuffer &buf, bool includeAlpha, int stackWidth) {
#ifdef USING_QT_UI
	req.Fail("Not supported on Qt yet, pull requests accepted");
	return false;
#else
	u8 *flipbuffer = nullptr;
	u32 w = (u32)-1;
	u32 h = (u32)-1;
	const u8 *buffer = ConvertBufferToScreenshot(buf, includeAlpha, flipbuffer, w, h);
	if (!buffer) {
		req.Fail("Internal error converting buffer for PNG encode");
		return false;
	}

	if (stackWidth > 0) {
		u32 totalPixels = w * h;
		w = stackWidth;
		while ((totalPixels % w) != 0)
			--w;
		h = totalPixels / w;
	}

	png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
	if (!png_ptr) {
		req.Fail("Internal error setting up PNG encoder (png_ptr)");
		return false;
	}
	png_infop info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr) {
		png_destroy_write_struct(&png_ptr, nullptr);
		req.Fail("Internal error setting up PNG encoder (info_ptr)");
		return false;
	}

	// Speed.  Wireless N should give 35 KB/ms.  For most devices, zlib/filters will cost more.
	png_set_compression_strategy(png_ptr, Z_RLE);
	png_set_compression_level(png_ptr, 1);
	png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_FILTER_NONE);

	auto &json = req.Respond();
	json.writeInt("width", w);
	json.writeInt("height", h);

	// Start a value...
	json.writeRaw("uri", "");
	req.Flush();
	// Now we'll write it directly to the stream.
	req.ws->AddFragment(false, "\"data:image/png;base64,");

	struct Context {
		DebuggerRequest *req;
		uint8_t buf[3];
		size_t bufSize;
	};
	Context ctx = { &req, {}, 0 };

	auto write = [](png_structp png_ptr, png_bytep data, png_size_t length) {
		auto ctx = (Context *)png_get_io_ptr(png_ptr);
		auto &req = *ctx->req;

		// If we buffered some bytes, fill to 3 bytes for a clean base64 encode.
		// This way we don't have padding.
		while (length > 0 && ctx->bufSize > 0 && ctx->bufSize != 3) {
			ctx->buf[ctx->bufSize++] = data[0];
			data++;
			length--;
		}

		if (ctx->bufSize == 3) {
			req.ws->AddFragment(false, Base64Encode(ctx->buf, ctx->bufSize));
			ctx->bufSize = 0;
		}
		assert(ctx->bufSize == 0 || length == 0);

		// Save bytes that would result in padding for next time.
		size_t toBuffer = length % 3;
		for (size_t i = 0; i < toBuffer; ++i) {
			ctx->buf[i] = data[length - toBuffer + i];
			ctx->bufSize++;
		}

		if (length > toBuffer) {
			req.ws->AddFragment(false, Base64Encode(data, length - toBuffer));
		}
	};
	auto flush = [](png_structp png_ptr) {
		// Nothing, just here to prevent stdio flush.
	};

	png_bytep *row_pointers = new png_bytep[h];
	u32 stride = includeAlpha ? w * 4 : w * 3;
	for (u32 i = 0; i < h; ++i) {
		row_pointers[i] = (u8 *)buffer + stride * i;
	}

	png_set_write_fn(png_ptr, &ctx, write, flush);
	int colorType = includeAlpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB;
	png_set_IHDR(png_ptr, info_ptr, w, h, 8, colorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
	png_set_rows(png_ptr, info_ptr, row_pointers);
	png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr);

	png_destroy_write_struct(&png_ptr, &info_ptr);
	delete [] row_pointers;
	delete [] flipbuffer;

	if (ctx.bufSize > 0) {
		req.ws->AddFragment(false, Base64Encode(ctx.buf, ctx.bufSize));
		ctx.bufSize = 0;
	}

	// End the string.
	req.ws->AddFragment(false, "\"");
	return true;
#endif
}
コード例 #27
0
ファイル: ipng.cpp プロジェクト: Bjoernke/livecode
extern "C" void fakeread(png_structp png_ptr, png_bytep data, png_size_t length)
{
	uint8_t **t_data_ptr = (uint8_t**)png_get_io_ptr(png_ptr);
	memcpy(data, *t_data_ptr, length);
	*t_data_ptr += length;
}
コード例 #28
0
static void PngReadData(png_structp png_ptr, png_bytep data, png_size_t length)
{
	uint8_t** d = (uint8_t**) png_get_io_ptr(png_ptr);
	memcpy(data, *d, length);
	(*d) += length;
}
コード例 #29
0
ファイル: png_io.hpp プロジェクト: DavidLiuGitHub/mapnik
void flush_data (png_structp png_ptr)
{
    T * out = static_cast<T*>(png_get_io_ptr(png_ptr));
    out->flush();
}
コード例 #30
0
ファイル: png_io.hpp プロジェクト: DavidLiuGitHub/mapnik
void write_data (png_structp png_ptr, png_bytep data, png_size_t length)
{
    T * out = static_cast<T*>(png_get_io_ptr(png_ptr));
    out->write(reinterpret_cast<char*>(data), length);
}