// Attempts to set the progression level to the given value, then re-read the // header. If reading the header fails, attempts to set the level to one level // below the initial level. If reading the header fails at level 0, an error // is returned. func (i *JP2Image) SetDynamicProgressionLevel(level int) error { onErr := func(err error) error { if level > 0 { goLog(6, fmt.Sprintf("Unable to set progression level to %d; trying again (%s)", level, err)) i.CleanupResources() return i.SetDynamicProgressionLevel(level - 1) } return err } goLog(6, fmt.Sprintf("Setting progression level to %d", level)) if err := i.initializeCodec(); err != nil { return onErr(err) } if C.opj_set_decoded_resolution_factor(i.codec, C.OPJ_UINT32(level)) == C.OPJ_FALSE { return onErr(errors.New("Error trying to set decoded resolution factor")) } if err := i.ReadHeader(); err != nil { return onErr(err) } return nil }
func NewImageTile(filename string, r image.Rectangle, width, height int) (err error, tile *ImageTile) { l_stream := C.opj_stream_create_default_file_stream_v3(C.CString(filename), 1) if l_stream == nil { return errors.New("failed to create stream"), nil } l_codec := C.opj_create_decompress(C.OPJ_CODEC_JP2) var parameters C.opj_dparameters_t C.opj_set_default_decoder_parameters(¶meters) level := desired_progression_level(r, width, height) log.Println("desired level:", level) //(parameters).cp_reduce = C.OPJ_UINT32(level) C.set_handlers(l_codec) if err == nil && C.opj_setup_decoder(l_codec, ¶meters) == C.OPJ_FALSE { err = errors.New("failed to setup decoder") } if err == nil && C.opj_set_decoded_resolution_factor(l_codec, C.OPJ_UINT32(level)) == C.OPJ_FALSE { err = errors.New("failed to set decode resolution factor") } var img *C.opj_image_t if err == nil && C.opj_read_header(l_stream, l_codec, &img) == C.OPJ_FALSE { err = errors.New("failed to read the header") } if err == nil { log.Println("num comps:", img.numcomps) log.Println("x0:", img.x0, "x1:", img.x1, "y0:", img.y0, "y1:", img.y1) } if err == nil && C.opj_set_decode_area(l_codec, img, C.OPJ_INT32(r.Min.X), C.OPJ_INT32(r.Min.Y), C.OPJ_INT32(r.Max.X), C.OPJ_INT32(r.Max.Y)) == C.OPJ_FALSE { err = errors.New("failed to set the decoded area") } if err == nil && C.opj_decode(l_codec, l_stream, img) == C.OPJ_FALSE { err = errors.New("failed to decode image") } if err == nil && C.opj_end_decompress(l_codec, l_stream) == C.OPJ_FALSE { err = errors.New("failed to decode image") } C.opj_stream_destroy_v3(l_stream) if l_codec != nil { C.opj_destroy_codec(l_codec) } if err == nil { var comps []C.opj_image_comp_t compsSlice := (*reflect.SliceHeader)((unsafe.Pointer(&comps))) compsSlice.Cap = int(img.numcomps) compsSlice.Len = int(img.numcomps) compsSlice.Data = uintptr(unsafe.Pointer(img.comps)) bounds := image.Rect(0, 0, int(comps[0].w), int(comps[0].h)) var data []int32 dataSlice := (*reflect.SliceHeader)((unsafe.Pointer(&data))) dataSlice.Cap = bounds.Dx() * bounds.Dy() dataSlice.Len = bounds.Dx() * bounds.Dy() dataSlice.Data = uintptr(unsafe.Pointer(comps[0].data)) tile = &ImageTile{data, bounds, bounds.Dx(), img} runtime.SetFinalizer(tile, func(it *ImageTile) { C.opj_image_destroy(it.img) }) } else { C.opj_image_destroy(img) } return }