def load_from_png(self, filename, x, y, feedback_cb=None, convert_to_srgb=True, **kwargs): """Load from a PNG, one tilerow at a time, discarding empty tiles. :param str filename: The file to load :param int x: X-coordinate at which to load the replacement data :param int y: Y-coordinate at which to load the replacement data :param bool convert_to_srgb: If True, convert to sRGB :param callable feedback_cb: Called every few tile rows :param dict \*\*kwargs: Ignored Raises a `lib.errors.FileHandlingError` with a descriptive string when conversion or PNG reading fails. """ dirty_tiles = set(self.tiledict.keys()) self.tiledict = {} state = {} state['buf'] = None # array of height N, width depends on image state['ty'] = y/N # current tile row being filled into buf state['frame_size'] = None def get_buffer(png_w, png_h): state['frame_size'] = x, y, png_w, png_h if feedback_cb: feedback_cb() buf_x0 = x/N*N buf_x1 = ((x+png_w-1)/N+1)*N buf_y0 = state['ty']*N buf_y1 = buf_y0+N buf_w = buf_x1-buf_x0 buf_h = buf_y1-buf_y0 assert buf_w % N == 0 assert buf_h == N if state['buf'] is not None: consume_buf() else: state['buf'] = numpy.empty((buf_h, buf_w, 4), 'uint8') png_x0 = x png_x1 = x+png_w subbuf = state['buf'][:, png_x0-buf_x0:png_x1-buf_x0] if 1: # optimize: only needed for first and last state['buf'].fill(0) png_y0 = max(buf_y0, y) png_y1 = min(buf_y0+buf_h, y+png_h) assert png_y1 > png_y0 subbuf = subbuf[png_y0-buf_y0:png_y1-buf_y0, :] state['ty'] += 1 return subbuf def consume_buf(): ty = state['ty']-1 for i in xrange(state['buf'].shape[1]/N): tx = x/N + i src = state['buf'][:, i*N:(i+1)*N, :] if src[:, :, 3].any(): with self.tile_request(tx, ty, readonly=False) as dst: mypaintlib.tile_convert_rgba8_to_rgba16(src, dst) if sys.platform == 'win32': filename_sys = filename.encode("utf-8") else: filename_sys = filename.encode(sys.getfilesystemencoding()) # FIXME: should not do that, should use open(unicode_object) try: flags = mypaintlib.load_png_fast_progressive( filename_sys, get_buffer, convert_to_srgb, ) except (IOError, OSError, RuntimeError) as ex: raise FileHandlingError(_("PNG reader failed: %s") % str(ex)) consume_buf() # also process the final chunk of data logger.debug("PNG loader flags: %r", flags) dirty_tiles.update(self.tiledict.keys()) bbox = lib.surface.get_tiles_bbox(dirty_tiles) self.notify_observers(*bbox) # return the bbox of the loaded image return state['frame_size']
def load_from_png(self, filename, x, y, feedback_cb=None): """Load from a PNG, one tilerow at a time, discarding empty tiles. """ dirty_tiles = set(self.tiledict.keys()) self.tiledict = {} state = {} state['buf'] = None # array of height N, width depends on image state['ty'] = y/N # current tile row being filled into buf state['frame_size'] = None def get_buffer(png_w, png_h): state['frame_size'] = x, y, png_w, png_h if feedback_cb: feedback_cb() buf_x0 = x/N*N buf_x1 = ((x+png_w-1)/N+1)*N buf_y0 = state['ty']*N buf_y1 = buf_y0+N buf_w = buf_x1-buf_x0 buf_h = buf_y1-buf_y0 assert buf_w % N == 0 assert buf_h == N if state['buf'] is not None: consume_buf() else: state['buf'] = empty((buf_h, buf_w, 4), 'uint8') png_x0 = x png_x1 = x+png_w subbuf = state['buf'][:,png_x0-buf_x0:png_x1-buf_x0] if 1: # optimize: only needed for first and last state['buf'].fill(0) png_y0 = max(buf_y0, y) png_y1 = min(buf_y0+buf_h, y+png_h) assert png_y1 > png_y0 subbuf = subbuf[png_y0-buf_y0:png_y1-buf_y0,:] state['ty'] += 1 return subbuf def consume_buf(): ty = state['ty']-1 for i in xrange(state['buf'].shape[1]/N): tx = x/N + i src = state['buf'][:,i*N:(i+1)*N,:] if src[:,:,3].any(): with self.tile_request(tx, ty, readonly=False) as dst: mypaintlib.tile_convert_rgba8_to_rgba16(src, dst) filename_sys = filename.encode(sys.getfilesystemencoding()) # FIXME: should not do that, should use open(unicode_object) flags = mypaintlib.load_png_fast_progressive(filename_sys, get_buffer) consume_buf() # also process the final chunk of data print flags dirty_tiles.update(self.tiledict.keys()) bbox = get_tiles_bbox(dirty_tiles) self.notify_observers(*bbox) # return the bbox of the loaded image return state['frame_size']
def load_from_png(self, filename, x, y, progress=None, convert_to_srgb=True, **kwargs): """Load from a PNG, one tilerow at a time, discarding empty tiles. :param str filename: The file to load :param int x: X-coordinate at which to load the replacement data :param int y: Y-coordinate at which to load the replacement data :param bool convert_to_srgb: If True, convert to sRGB :param progress: Unsized UI feedback obj. :type progress: lib.feedback.Progress or None :param dict \*\*kwargs: Ignored Raises a `lib.errors.FileHandlingError` with a descriptive string when conversion or PNG reading fails. """ if not progress: progress = lib.feedback.Progress() # Catch this error up front, since the code below hides it. if progress.items is not None: raise ValueError("progress arg must be unsized") dirty_tiles = set(self.tiledict.keys()) self.tiledict = {} ty0 = int(y // N) state = {} state['buf'] = None # array of height N, width depends on image state['ty'] = ty0 # current tile row being filled into buf state['frame_size'] = None state['progress'] = progress def get_buffer(png_w, png_h): if state["frame_size"] is None: if state['progress']: ty_final = int((y + png_h) // N) # We have to handle feedback exceptions ourself try: state["progress"].items = ty_final - ty0 except Exception: logger.exception("setting progress.items failed") state["progress"] = None state['frame_size'] = (x, y, png_w, png_h) buf_x0 = x // N * N buf_x1 = ((x + png_w - 1) // N + 1) * N buf_y0 = state['ty']*N buf_y1 = buf_y0+N buf_w = buf_x1-buf_x0 buf_h = buf_y1-buf_y0 assert buf_w % N == 0 assert buf_h == N if state['buf'] is not None: consume_buf() else: state['buf'] = np.empty((buf_h, buf_w, 4), 'uint8') png_x0 = x png_x1 = x+png_w subbuf = state['buf'][:, png_x0-buf_x0:png_x1-buf_x0] if 1: # optimize: only needed for first and last state['buf'].fill(0) png_y0 = max(buf_y0, y) png_y1 = min(buf_y0+buf_h, y+png_h) assert png_y1 > png_y0 subbuf = subbuf[png_y0-buf_y0:png_y1-buf_y0, :] state['ty'] += 1 return subbuf def consume_buf(): ty = state['ty']-1 for i in xrange(state['buf'].shape[1] // N): tx = x // N + i src = state['buf'][:, i*N:(i+1)*N, :] if src[:, :, 3].any(): with self.tile_request(tx, ty, readonly=False) as dst: mypaintlib.tile_convert_rgba8_to_rgba16(src, dst) if state["progress"]: try: state["progress"].completed(ty - ty0) except Exception: logger.exception("Progress.completed() failed") state["progress"] = None if sys.platform == 'win32': filename_sys = filename.encode("utf-8") else: filename_sys = filename.encode(sys.getfilesystemencoding()) # FIXME: should not do that, should use open(unicode_object) try: flags = mypaintlib.load_png_fast_progressive( filename_sys, get_buffer, convert_to_srgb, ) except (IOError, OSError, RuntimeError) as ex: raise FileHandlingError(_("PNG reader failed: %s") % str(ex)) consume_buf() # also process the final chunk of data progress.close() logger.debug("PNG loader flags: %r", flags) dirty_tiles.update(self.tiledict.keys()) bbox = lib.surface.get_tiles_bbox(dirty_tiles) self.notify_observers(*bbox) # return the bbox of the loaded image return state['frame_size']
def load_from_png(self, filename, x, y, feedback_cb=None, convert_to_srgb=True, **kwargs): """Load from a PNG, one tilerow at a time, discarding empty tiles. :param str filename: The file to load :param int x: X-coordinate at which to load the replacement data :param int y: Y-coordinate at which to load the replacement data :param bool convert_to_srgb: If True, convert to sRGB :param callable feedback_cb: Called every few tile rows :param dict \*\*kwargs: Ignored Raises a `lib.errors.FileHandlingError` with a descriptive string when conversion or PNG reading fails. """ dirty_tiles = set(self.tiledict.keys()) self.tiledict = {} state = {} state['buf'] = None # array of height N, width depends on image state['ty'] = y / N # current tile row being filled into buf state['frame_size'] = None def get_buffer(png_w, png_h): state['frame_size'] = x, y, png_w, png_h if feedback_cb: feedback_cb() buf_x0 = x / N * N buf_x1 = ((x + png_w - 1) / N + 1) * N buf_y0 = state['ty'] * N buf_y1 = buf_y0 + N buf_w = buf_x1 - buf_x0 buf_h = buf_y1 - buf_y0 assert buf_w % N == 0 assert buf_h == N if state['buf'] is not None: consume_buf() else: state['buf'] = numpy.empty((buf_h, buf_w, 4), 'uint8') png_x0 = x png_x1 = x + png_w subbuf = state['buf'][:, png_x0 - buf_x0:png_x1 - buf_x0] if 1: # optimize: only needed for first and last state['buf'].fill(0) png_y0 = max(buf_y0, y) png_y1 = min(buf_y0 + buf_h, y + png_h) assert png_y1 > png_y0 subbuf = subbuf[png_y0 - buf_y0:png_y1 - buf_y0, :] state['ty'] += 1 return subbuf def consume_buf(): ty = state['ty'] - 1 for i in xrange(state['buf'].shape[1] / N): tx = x / N + i src = state['buf'][:, i * N:(i + 1) * N, :] if src[:, :, 3].any(): with self.tile_request(tx, ty, readonly=False) as dst: mypaintlib.tile_convert_rgba8_to_rgba16(src, dst) if sys.platform == 'win32': filename_sys = filename.encode("utf-8") else: filename_sys = filename.encode(sys.getfilesystemencoding( )) # FIXME: should not do that, should use open(unicode_object) try: flags = mypaintlib.load_png_fast_progressive( filename_sys, get_buffer, convert_to_srgb, ) except (IOError, OSError, RuntimeError) as ex: raise FileHandlingError(_("PNG reader failed: %s") % str(ex)) consume_buf() # also process the final chunk of data logger.debug("PNG loader flags: %r", flags) dirty_tiles.update(self.tiledict.keys()) bbox = lib.surface.get_tiles_bbox(dirty_tiles) self.notify_observers(*bbox) # return the bbox of the loaded image return state['frame_size']
def load_from_png(self, filename, x, y, feedback_cb=None): """Load from a PNG, one tilerow at a time, discarding empty tiles. """ dirty_tiles = set(self.tiledict.keys()) self.tiledict = {} state = {} state['buf'] = None # array of height N, width depends on image state['ty'] = y / N # current tile row being filled into buf state['frame_size'] = None def get_buffer(png_w, png_h): state['frame_size'] = x, y, png_w, png_h if feedback_cb: feedback_cb() buf_x0 = x / N * N buf_x1 = ((x + png_w - 1) / N + 1) * N buf_y0 = state['ty'] * N buf_y1 = buf_y0 + N buf_w = buf_x1 - buf_x0 buf_h = buf_y1 - buf_y0 assert buf_w % N == 0 assert buf_h == N if state['buf'] is not None: consume_buf() else: state['buf'] = numpy.empty((buf_h, buf_w, 4), 'uint8') png_x0 = x png_x1 = x + png_w subbuf = state['buf'][:, png_x0 - buf_x0:png_x1 - buf_x0] if 1: # optimize: only needed for first and last state['buf'].fill(0) png_y0 = max(buf_y0, y) png_y1 = min(buf_y0 + buf_h, y + png_h) assert png_y1 > png_y0 subbuf = subbuf[png_y0 - buf_y0:png_y1 - buf_y0, :] state['ty'] += 1 return subbuf def consume_buf(): ty = state['ty'] - 1 for i in xrange(state['buf'].shape[1] / N): tx = x / N + i src = state['buf'][:, i * N:(i + 1) * N, :] if src[:, :, 3].any(): with self.tile_request(tx, ty, readonly=False) as dst: mypaintlib.tile_convert_rgba8_to_rgba16(src, dst) filename_sys = filename.encode(sys.getfilesystemencoding( )) # FIXME: should not do that, should use open(unicode_object) flags = mypaintlib.load_png_fast_progressive(filename_sys, get_buffer) consume_buf() # also process the final chunk of data logger.debug("PNG loader flags: %r", flags) dirty_tiles.update(self.tiledict.keys()) bbox = get_tiles_bbox(dirty_tiles) self.notify_observers(*bbox) # return the bbox of the loaded image return state['frame_size']