/** * gsft_png_user_read_data(): libpng user-specified read data function. * Used to read PNG data from memory instead of from a file. * @param png_ptr Pointer to the PNG information struct. * @param png_bytep Pointer to memory to write PNG data to. * @param length Length of data requested. */ void gsft_png_user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { // Get the pointer to the gsft_png_mem_t struct. gsft_png_mem_t *png_mem = (gsft_png_mem_t*)ppng_get_io_ptr(png_ptr); if (!png_mem) return; // Make sure there's enough data available. if (png_mem->pos + length > png_mem->length) { // Not enough data is available. // TODO: This may still result in a crash. Use longjmp()? // Zero the buffer. memset(data, 0x00, length); // Return the rest of the buffer. length = png_mem->length - png_mem->pos; if (length <= 0) return; } // Copy the data. memcpy(data, &(png_mem->data[png_mem->pos]), length); // Increment the data position. png_mem->pos += length; }
static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { IStream *stream = ppng_get_io_ptr(png_ptr); HRESULT hr; ULONG bytesread; hr = IStream_Read(stream, data, length, &bytesread); if (FAILED(hr) || bytesread != length) { ppng_error(png_ptr, "failed reading data"); } }
static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { PngEncoder *This = ppng_get_io_ptr(png_ptr); HRESULT hr; ULONG byteswritten; hr = IStream_Write(This->stream, data, length, &byteswritten); if (FAILED(hr) || byteswritten != length) { ppng_error(png_ptr, "failed writing data"); } }