private static Kdu_coords getReferenceExpansion( int reference_component, Kdu_channel_mapping channels, Kdu_codestream codestream) throws KduException { int c; Kdu_coords ref_subs = new Kdu_coords(); Kdu_coords subs = new Kdu_coords(); codestream.Get_subsampling(reference_component, ref_subs); Kdu_coords min_subs = new Kdu_coords(); min_subs.Assign(ref_subs); for (c = 0; c < channels.Get_num_channels(); c++) { codestream.Get_subsampling(channels.Get_source_component(c), subs); if (subs.Get_x() < min_subs.Get_x()) min_subs.Set_x(subs.Get_x()); if (subs.Get_y() < min_subs.Get_y()) min_subs.Set_y(subs.Get_y()); } Kdu_coords expansion = new Kdu_coords(); expansion.Set_x(ref_subs.Get_x() / min_subs.Get_x()); expansion.Set_y(ref_subs.Get_y() / min_subs.Get_y()); for (c = 0; c < channels.Get_num_channels(); c++) { codestream.Get_subsampling(channels.Get_source_component(c), subs); if ((((subs.Get_x() * expansion.Get_x()) % ref_subs.Get_x()) != 0) || (((subs.Get_y() * expansion.Get_y()) % ref_subs.Get_y()) != 0)) { Kdu_global.Kdu_print_error( "The supplied JP2 file contains color channels " + "whose sub-sampling factors are not integer " + "multiples of one another."); codestream.Apply_input_restrictions( 0, 1, 0, 0, null, Kdu_global.KDU_WANT_OUTPUT_COMPONENTS); channels.Configure(codestream); expansion = new Kdu_coords(1, 1); } } return expansion; }
public BufferedImage extract() throws DjatokaException { boolean useRegion = false; int left = 0; int top = 0; int width = 50; int height = 50; boolean useleftDouble = false; Double leftDouble = 0.0; boolean usetopDouble = false; Double topDouble = 0.0; boolean usewidthDouble = false; Double widthDouble = 0.0; boolean useheightDouble = false; Double heightDouble = 0.0; if (params.getRegion() != null) { StringTokenizer st = new StringTokenizer(params.getRegion(), "{},"); String token; // top if ((token = st.nextToken()).contains(".")) { topDouble = Double.parseDouble(token); usetopDouble = true; } else top = Integer.parseInt(token); // left if ((token = st.nextToken()).contains(".")) { leftDouble = Double.parseDouble(token); useleftDouble = true; } else left = Integer.parseInt(token); // height if ((token = st.nextToken()).contains(".")) { heightDouble = Double.parseDouble(token); useheightDouble = true; } else height = Integer.parseInt(token); // width if ((token = st.nextToken()).contains(".")) { widthDouble = Double.parseDouble(token); usewidthDouble = true; } else width = Integer.parseInt(token); useRegion = true; } try { if (is != null) { File f = File.createTempFile("tmp", ".jp2"); f.deleteOnExit(); FileOutputStream fos = new FileOutputStream(f); sourceFile = f.getAbsolutePath(); IOUtils.copyStream(is, fos); is.close(); fos.close(); } } catch (IOException e) { throw new DjatokaException(e); } try { Jp2_source inputSource = new Jp2_source(); Kdu_compressed_source input = null; Jp2_family_src jp2_family_in = new Jp2_family_src(); Jp2_locator loc = new Jp2_locator(); jp2_family_in.Open(sourceFile, true); inputSource.Open(jp2_family_in, loc); inputSource.Read_header(); input = inputSource; Kdu_codestream codestream = new Kdu_codestream(); codestream.Create(input); Kdu_channel_mapping channels = new Kdu_channel_mapping(); if (inputSource.Exists()) channels.Configure(inputSource, false); else channels.Configure(codestream); int ref_component = channels.Get_source_component(0); Kdu_coords ref_expansion = getReferenceExpansion(ref_component, channels, codestream); Kdu_dims image_dims = new Kdu_dims(); codestream.Get_dims(ref_component, image_dims); Kdu_coords imageSize = image_dims.Access_size(); Kdu_coords imagePosition = image_dims.Access_pos(); if (useleftDouble) left = imagePosition.Get_x() + (int) Math.round(leftDouble * imageSize.Get_x()); if (usetopDouble) top = imagePosition.Get_y() + (int) Math.round(topDouble * imageSize.Get_y()); if (useheightDouble) height = (int) Math.round(heightDouble * imageSize.Get_y()); if (usewidthDouble) width = (int) Math.round(widthDouble * imageSize.Get_x()); if (useRegion) { imageSize.Set_x(width); imageSize.Set_y(height); imagePosition.Set_x(left); imagePosition.Set_y(top); } int reduce = 1 << params.getLevelReductionFactor(); imageSize.Set_x(imageSize.Get_x() * ref_expansion.Get_x()); imageSize.Set_y(imageSize.Get_y() * ref_expansion.Get_y()); imagePosition.Set_x( imagePosition.Get_x() * ref_expansion.Get_x() / reduce - ((ref_expansion.Get_x() / reduce - 1) / 2)); imagePosition.Set_y( imagePosition.Get_y() * ref_expansion.Get_y() / reduce - ((ref_expansion.Get_y() / reduce - 1) / 2)); Kdu_dims view_dims = new Kdu_dims(); view_dims.Assign(image_dims); view_dims.Access_size().Set_x(imageSize.Get_x()); view_dims.Access_size().Set_y(imageSize.Get_y()); int region_buf_size = imageSize.Get_x() * imageSize.Get_y(); int[] region_buf = new int[region_buf_size]; Kdu_region_decompressor decompressor = new Kdu_region_decompressor(); decompressor.Start( codestream, channels, -1, params.getLevelReductionFactor(), 16384, image_dims, ref_expansion, new Kdu_coords(1, 1), false, Kdu_global.KDU_WANT_OUTPUT_COMPONENTS); Kdu_dims new_region = new Kdu_dims(); Kdu_dims incomplete_region = new Kdu_dims(); Kdu_coords viewSize = view_dims.Access_size(); incomplete_region.Assign(image_dims); int[] imgBuffer = new int[viewSize.Get_x() * viewSize.Get_y()]; int[] kduBuffer = null; while (decompressor.Process( region_buf, image_dims.Access_pos(), 0, 0, region_buf_size, incomplete_region, new_region)) { Kdu_coords newOffset = new_region.Access_pos(); Kdu_coords newSize = new_region.Access_size(); newOffset.Subtract(view_dims.Access_pos()); kduBuffer = region_buf; int imgBuffereIdx = newOffset.Get_x() + newOffset.Get_y() * viewSize.Get_x(); int kduBufferIdx = 0; int xDiff = viewSize.Get_x() - newSize.Get_x(); for (int j = 0; j < newSize.Get_y(); j++, imgBuffereIdx += xDiff) { for (int i = 0; i < newSize.Get_x(); i++) { imgBuffer[imgBuffereIdx++] = kduBuffer[kduBufferIdx++]; } } } BufferedImage image = new BufferedImage(imageSize.Get_x(), imageSize.Get_y(), BufferedImage.TYPE_INT_RGB); image.setRGB(0, 0, viewSize.Get_x(), viewSize.Get_y(), imgBuffer, 0, viewSize.Get_x()); if (params.getRotationDegree() > 0) { image = ImageProcessingUtils.rotate(image, params.getRotationDegree()); } decompressor.Native_destroy(); channels.Native_destroy(); if (codestream.Exists()) codestream.Destroy(); inputSource.Native_destroy(); input.Native_destroy(); jp2_family_in.Native_destroy(); return image; } catch (KduException e) { e.printStackTrace(); throw new DjatokaException(e); } catch (Exception e) { e.printStackTrace(); throw new DjatokaException(e); } }