diff options
Diffstat (limited to 'hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java')
-rw-r--r-- | hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java | 831 |
1 files changed, 831 insertions, 0 deletions
diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java b/hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java new file mode 100644 index 000000000..bae1270cc --- /dev/null +++ b/hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java @@ -0,0 +1,831 @@ +package com.android.hierarchyviewer.ui; + +import com.android.ddmlib.IDevice; +import com.android.ddmlib.RawImage; +import com.android.hierarchyviewer.scene.ViewNode; +import com.android.hierarchyviewer.ui.util.IconLoader; +import com.android.hierarchyviewer.ui.util.PngFileFilter; +import com.android.hierarchyviewer.util.WorkerThread; + +import java.awt.AlphaComposite; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +import javax.imageio.ImageIO; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSlider; +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; +import javax.swing.Timer; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +class ScreenViewer extends JPanel implements ActionListener { + private final Workspace workspace; + private final IDevice device; + + private GetScreenshotTask task; + private BufferedImage image; + private int[] scanline; + private volatile boolean isLoading; + + private BufferedImage overlay; + private AlphaComposite overlayAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f); + + private ScreenViewer.LoupeStatus status; + private ScreenViewer.LoupeViewer loupe; + private ScreenViewer.Crosshair crosshair; + + private int zoom = 8; + private int y = 0; + + private Timer timer; + private ViewNode node; + + private JSlider zoomSlider; + + ScreenViewer(Workspace workspace, IDevice device, int spacing) { + setLayout(new GridBagLayout()); + setOpaque(false); + + this.workspace = workspace; + this.device = device; + + timer = new Timer(5000, this); + timer.setInitialDelay(0); + timer.setRepeats(true); + + JPanel panel = buildViewerAndControls(); + add(panel, new GridBagConstraints(0, 0, 1, 1, 0.3f, 1.0f, + GridBagConstraints.FIRST_LINE_START, GridBagConstraints.BOTH, + new Insets(0, 0, 0, 0), 0, 0)); + + JPanel loupePanel = buildLoupePanel(spacing); + add(loupePanel, new GridBagConstraints(1, 0, 1, 1, 0.7f, 1.0f, + GridBagConstraints.FIRST_LINE_START, GridBagConstraints.BOTH, + new Insets(0, 0, 0, 0), 0, 0)); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + timer.start(); + } + }); + } + + private JPanel buildLoupePanel(int spacing) { + loupe = new LoupeViewer(); + loupe.addMouseWheelListener(new WheelZoomListener()); + CrosshairPanel crosshairPanel = new CrosshairPanel(loupe); + + JPanel loupePanel = new JPanel(new BorderLayout()); + loupePanel.add(crosshairPanel); + status = new LoupeStatus(); + loupePanel.add(status, BorderLayout.SOUTH); + + loupePanel.setBorder(BorderFactory.createEmptyBorder(0, spacing, 0, 0)); + return loupePanel; + } + + private class WheelZoomListener implements MouseWheelListener { + public void mouseWheelMoved(MouseWheelEvent e) { + if (zoomSlider != null) { + int val = zoomSlider.getValue(); + val -= e.getWheelRotation() * 2; + zoomSlider.setValue(val); + } + } + } + + private JPanel buildViewerAndControls() { + JPanel panel = new JPanel(new GridBagLayout()); + crosshair = new Crosshair(new ScreenshotViewer()); + crosshair.addMouseWheelListener(new WheelZoomListener()); + JScrollPane scroller = new JScrollPane(crosshair); + scroller.setPreferredSize(new Dimension(320, 480)); + scroller.setBorder(null); + panel.add(scroller, + new GridBagConstraints(0, y++, 2, 1, 1.0f, 1.0f, + GridBagConstraints.FIRST_LINE_START, GridBagConstraints.BOTH, + new Insets(0, 0, 0, 0), 0, 0)); + buildSlider(panel, "Overlay:", "0%", "100%", 0, 100, 30, 1).addChangeListener( + new ChangeListener() { + public void stateChanged(ChangeEvent event) { + float opacity = ((JSlider) event.getSource()).getValue() / 100.0f; + overlayAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity); + repaint(); + } + }); + buildOverlayExtraControls(panel); + buildSlider(panel, "Refresh Rate:", "1s", "40s", 1, 40, 5, 1).addChangeListener( + new ChangeListener() { + public void stateChanged(ChangeEvent event) { + int rate = ((JSlider) event.getSource()).getValue() * 1000; + timer.setDelay(rate); + timer.setInitialDelay(0); + timer.restart(); + } + }); + zoomSlider = buildSlider(panel, "Zoom:", "2x", "24x", 2, 24, 8, 2); + zoomSlider.addChangeListener( + new ChangeListener() { + public void stateChanged(ChangeEvent event) { + zoom = ((JSlider) event.getSource()).getValue(); + loupe.clearGrid = true; + loupe.moveToPoint(crosshair.crosshair.x, crosshair.crosshair.y); + repaint(); + } + }); + panel.add(Box.createVerticalGlue(), + new GridBagConstraints(0, y++, 2, 1, 1.0f, 1.0f, + GridBagConstraints.FIRST_LINE_START, GridBagConstraints.NONE, + new Insets(0, 0, 0, 0), 0, 0)); + return panel; + } + + private void buildOverlayExtraControls(JPanel panel) { + JPanel extras = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); + + JButton loadOverlay = new JButton("Load..."); + loadOverlay.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent event) { + SwingWorker<?, ?> worker = openOverlay(); + if (worker != null) { + worker.execute(); + } + } + }); + extras.add(loadOverlay); + + JCheckBox showInLoupe = new JCheckBox("Show in Loupe"); + showInLoupe.setSelected(false); + showInLoupe.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent event) { + loupe.showOverlay = ((JCheckBox) event.getSource()).isSelected(); + loupe.repaint(); + } + }); + extras.add(showInLoupe); + + panel.add(extras, new GridBagConstraints(1, y++, 1, 1, 1.0f, 0.0f, + GridBagConstraints.LINE_START, GridBagConstraints.NONE, + new Insets(0, 0, 0, 0), 0, 0)); + } + + public SwingWorker<?, ?> openOverlay() { + JFileChooser chooser = new JFileChooser(); + chooser.setFileFilter(new PngFileFilter()); + int choice = chooser.showOpenDialog(this); + if (choice == JFileChooser.APPROVE_OPTION) { + return new OpenOverlayTask(chooser.getSelectedFile()); + } else { + return null; + } + } + + private JSlider buildSlider(JPanel panel, String title, String minName, String maxName, + int min, int max, int value, int tick) { + panel.add(new JLabel(title), new GridBagConstraints(0, y, 1, 1, 1.0f, 0.0f, + GridBagConstraints.LINE_END, GridBagConstraints.NONE, + new Insets(0, 0, 0, 6), 0, 0)); + JPanel sliderPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); + sliderPanel.add(new JLabel(minName)); + JSlider slider = new JSlider(min, max, value); + slider.setMinorTickSpacing(tick); + slider.setMajorTickSpacing(tick); + slider.setSnapToTicks(true); + sliderPanel.add(slider); + sliderPanel.add(new JLabel(maxName)); + panel.add(sliderPanel, new GridBagConstraints(1, y++, 1, 1, 1.0f, 0.0f, + GridBagConstraints.FIRST_LINE_START, GridBagConstraints.NONE, + new Insets(0, 0, 0, 0), 0, 0)); + return slider; + } + + void stop() { + timer.stop(); + } + + void start() { + timer.start(); + } + + void select(ViewNode node) { + this.node = node; + repaint(); + } + + class LoupeViewer extends JComponent { + private final Color lineColor = new Color(1.0f, 1.0f, 1.0f, 0.3f); + + private int width; + private int height; + private BufferedImage grid; + private int left; + private int top; + public boolean clearGrid; + + private final Rectangle clip = new Rectangle(); + private boolean showOverlay = false; + + LoupeViewer() { + addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent event) { + moveToPoint(event); + } + }); + addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseDragged(MouseEvent event) { + moveToPoint(event); + } + }); + } + + @Override + protected void paintComponent(Graphics g) { + if (isLoading) { + return; + } + + g.translate(-left, -top); + + if (image != null) { + Graphics2D g2 = (Graphics2D) g.create(); + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); + g2.scale(zoom, zoom); + g2.drawImage(image, 0, 0, null); + if (overlay != null && showOverlay) { + g2.setComposite(overlayAlpha); + g2.drawImage(overlay, 0, image.getHeight() - overlay.getHeight(), null); + } + g2.dispose(); + } + + int width = getWidth(); + int height = getHeight(); + + Graphics2D g2 = null; + if (width != this.width || height != this.height) { + this.width = width; + this.height = height; + + grid = new BufferedImage(width + zoom + 1, height + zoom + 1, + BufferedImage.TYPE_INT_ARGB); + clearGrid = true; + g2 = grid.createGraphics(); + } else if (clearGrid) { + g2 = grid.createGraphics(); + g2.setComposite(AlphaComposite.Clear); + g2.fillRect(0, 0, grid.getWidth(), grid.getHeight()); + g2.setComposite(AlphaComposite.SrcOver); + } + + if (clearGrid) { + clearGrid = false; + + g2.setColor(lineColor); + width += zoom; + height += zoom; + + for (int x = zoom; x <= width; x += zoom) { + g2.drawLine(x, 0, x, height); + } + + for (int y = 0; y <= height; y += zoom) { + g2.drawLine(0, y, width, y); + } + + g2.dispose(); + } + + if (image != null) { + g.getClipBounds(clip); + g.clipRect(0, 0, image.getWidth() * zoom + 1, image.getHeight() * zoom + 1); + g.drawImage(grid, clip.x - clip.x % zoom, clip.y - clip.y % zoom, null); + } + + g.translate(left, top); + } + + void moveToPoint(MouseEvent event) { + int x = Math.max(0, Math.min((event.getX() + left) / zoom, image.getWidth() - 1)); + int y = Math.max(0, Math.min((event.getY() + top) / zoom, image.getHeight() - 1)); + moveToPoint(x, y); + crosshair.moveToPoint(x, y); + } + + void moveToPoint(int x, int y) { + left = x * zoom - width / 2 + zoom / 2; + top = y * zoom - height / 2 + zoom / 2; + repaint(); + } + } + + class LoupeStatus extends JPanel { + private JLabel xLabel; + private JLabel yLabel; + private JLabel rLabel; + private JLabel gLabel; + private JLabel bLabel; + private JLabel hLabel; + private ScreenViewer.LoupeStatus.ColoredSquare square; + private Color color; + + LoupeStatus() { + setOpaque(true); + setLayout(new GridBagLayout()); + setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); + + square = new ColoredSquare(); + add(square, new GridBagConstraints(0, 0, 1, 2, 0.0f, 0.0f, + GridBagConstraints.LINE_START, GridBagConstraints.NONE, + new Insets(0, 0, 0, 12), 0, 0 )); + + JLabel label; + + add(label = new JLabel("#ffffff"), new GridBagConstraints(0, 2, 1, 1, 0.0f, 0.0f, + GridBagConstraints.LINE_START, GridBagConstraints.NONE, + new Insets(0, 0, 0, 12), 0, 0 )); + label.setForeground(Color.WHITE); + hLabel = label; + + add(label = new JLabel("R:"), new GridBagConstraints(1, 0, 1, 1, 0.0f, 0.0f, + GridBagConstraints.LINE_START, GridBagConstraints.NONE, + new Insets(0, 6, 0, 6), 0, 0 )); + label.setForeground(Color.WHITE); + add(label = new JLabel("255"), new GridBagConstraints(2, 0, 1, 1, 0.0f, 0.0f, + GridBagConstraints.LINE_START, GridBagConstraints.NONE, + new Insets(0, 0, 0, 12), 0, 0 )); + label.setForeground(Color.WHITE); + rLabel = label; + + add(label = new JLabel("G:"), new GridBagConstraints(1, 1, 1, 1, 0.0f, 0.0f, + GridBagConstraints.LINE_START, GridBagConstraints.NONE, + new Insets(0, 6, 0, 6), 0, 0 )); + label.setForeground(Color.WHITE); + add(label = new JLabel("255"), new GridBagConstraints(2, 1, 1, 1, 0.0f, 0.0f, + GridBagConstraints.LINE_START, GridBagConstraints.NONE, + new Insets(0, 0, 0, 12), 0, 0 )); + label.setForeground(Color.WHITE); + gLabel = label; + + add(label = new JLabel("B:"), new GridBagConstraints(1, 2, 1, 1, 0.0f, 0.0f, + GridBagConstraints.LINE_START, GridBagConstraints.NONE, + new Insets(0, 6, 0, 6), 0, 0 )); + label.setForeground(Color.WHITE); + add(label = new JLabel("255"), new GridBagConstraints(2, 2, 1, 1, 0.0f, 0.0f, + GridBagConstraints.LINE_START, GridBagConstraints.NONE, + new Insets(0, 0, 0, 12), 0, 0 )); + label.setForeground(Color.WHITE); + bLabel = label; + + add(label = new JLabel("X:"), new GridBagConstraints(3, 0, 1, 1, 0.0f, 0.0f, + GridBagConstraints.LINE_START, GridBagConstraints.NONE, + new Insets(0, 6, 0, 6), 0, 0 )); + label.setForeground(Color.WHITE); + add(label = new JLabel("0 px"), new GridBagConstraints(4, 0, 1, 1, 0.0f, 0.0f, + GridBagConstraints.LINE_START, GridBagConstraints.NONE, + new Insets(0, 0, 0, 12), 0, 0 )); + label.setForeground(Color.WHITE); + xLabel = label; + + add(label = new JLabel("Y:"), new GridBagConstraints(3, 1, 1, 1, 0.0f, 0.0f, + GridBagConstraints.LINE_START, GridBagConstraints.NONE, + new Insets(0, 6, 0, 6), 0, 0 )); + label.setForeground(Color.WHITE); + add(label = new JLabel("0 px"), new GridBagConstraints(4, 1, 1, 1, 0.0f, 0.0f, + GridBagConstraints.LINE_START, GridBagConstraints.NONE, + new Insets(0, 0, 0, 12), 0, 0 )); + label.setForeground(Color.WHITE); + yLabel = label; + + add(Box.createHorizontalGlue(), new GridBagConstraints(5, 0, 1, 1, 1.0f, 0.0f, + GridBagConstraints.LINE_START, GridBagConstraints.BOTH, + new Insets(0, 0, 0, 0), 0, 0 )); + } + + @Override + protected void paintComponent(Graphics g) { + g.setColor(Color.BLACK); + g.fillRect(0, 0, getWidth(), getHeight()); + } + + void showPixel(int x, int y) { + xLabel.setText(x + " px"); + yLabel.setText(y + " px"); + + int pixel = image.getRGB(x, y); + color = new Color(pixel); + hLabel.setText("#" + Integer.toHexString(pixel)); + rLabel.setText(String.valueOf((pixel >> 16) & 0xff)); + gLabel.setText(String.valueOf((pixel >> 8) & 0xff)); + bLabel.setText(String.valueOf((pixel ) & 0xff)); + + square.repaint(); + } + + private class ColoredSquare extends JComponent { + @Override + public Dimension getPreferredSize() { + Dimension d = super.getPreferredSize(); + d.width = 60; + d.height = 30; + return d; + } + + @Override + protected void paintComponent(Graphics g) { + g.setColor(color); + g.fillRect(0, 0, getWidth(), getHeight()); + + g.setColor(Color.WHITE); + g.drawRect(0, 0, getWidth() - 1, getHeight() - 1); + } + } + } + + class Crosshair extends JPanel { + // magenta = 0xff5efe + private final Color crosshairColor = new Color(0x00ffff); + Point crosshair = new Point(); + private int width; + private int height; + private final ScreenshotViewer screenshotViewer; + + Crosshair(ScreenshotViewer screenshotViewer) { + this.screenshotViewer = screenshotViewer; + setOpaque(true); + setLayout(new BorderLayout()); + add(screenshotViewer); + addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent event) { + moveToPoint(event); + } + }); + addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseDragged(MouseEvent event) { + moveToPoint(event); + } + }); + } + + void moveToPoint(int x, int y) { + crosshair.x = x; + crosshair.y = y; + status.showPixel(crosshair.x, crosshair.y); + repaint(); + } + + private void moveToPoint(MouseEvent event) { + crosshair.x = Math.max(0, Math.min(image.getWidth() - 1, event.getX())); + crosshair.y = Math.max(0, Math.min(image.getHeight() - 1, event.getY())); + loupe.moveToPoint(crosshair.x, crosshair.y); + status.showPixel(crosshair.x, crosshair.y); + + repaint(); + } + + @Override + public Dimension getPreferredSize() { + return screenshotViewer.getPreferredSize(); + } + + @Override + public Dimension getMaximumSize() { + return screenshotViewer.getPreferredSize(); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + + if (crosshair == null || width != getWidth() || height != getHeight()) { + width = getWidth(); + height = getHeight(); + crosshair = new Point(width / 2, height / 2); + } + + g.setColor(crosshairColor); + + g.drawLine(crosshair.x, 0, crosshair.x, height); + g.drawLine(0, crosshair.y, width, crosshair.y); + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + g.setColor(Color.BLACK); + g.fillRect(0, 0, getWidth(), getHeight()); + } + } + + class ScreenshotViewer extends JComponent { + private final Color boundsColor = new Color(0xff5efe); + + ScreenshotViewer() { + setOpaque(true); + } + + @Override + protected void paintComponent(Graphics g) { + g.setColor(Color.BLACK); + g.fillRect(0, 0, getWidth(), getHeight()); + + if (isLoading) { + return; + } + + if (image != null) { + g.drawImage(image, 0, 0, null); + if (overlay != null) { + Graphics2D g2 = (Graphics2D) g.create(); + g2.setComposite(overlayAlpha); + g2.drawImage(overlay, 0, image.getHeight() - overlay.getHeight(), null); + } + } + + if (node != null) { + Graphics s = g.create(); + s.setColor(boundsColor); + ViewNode p = node.parent; + while (p != null) { + s.translate(p.left - p.scrollX, p.top - p.scrollY); + p = p.parent; + } + s.drawRect(node.left, node.top, node.width - 1, node.height - 1); + s.translate(node.left, node.top); + + s.setXORMode(Color.WHITE); + if ((node.paddingBottom | node.paddingLeft | + node.paddingTop | node.paddingRight) != 0) { + s.setColor(Color.BLACK); + s.drawRect(node.paddingLeft, node.paddingTop, + node.width - node.paddingRight - node.paddingLeft - 1, + node.height - node.paddingBottom - node.paddingTop - 1); + } + if (node.hasMargins && (node.marginLeft | node.marginBottom | + node.marginRight | node.marginRight) != 0) { + s.setColor(Color.BLACK); + s.drawRect(-node.marginLeft, -node.marginTop, + node.marginLeft + node.width + node.marginRight - 1, + node.marginTop + node.height + node.marginBottom - 1); + } + + s.dispose(); + } + } + + @Override + public Dimension getPreferredSize() { + if (image == null) { + return new Dimension(320, 480); + } + return new Dimension(image.getWidth(), image.getHeight()); + } + } + + private class CrosshairPanel extends JPanel { + private final Color crosshairColor = new Color(0xff5efe); + private final Insets insets = new Insets(0, 0, 0, 0); + + CrosshairPanel(LoupeViewer loupe) { + setLayout(new BorderLayout()); + add(loupe); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + + g.setColor(crosshairColor); + + int width = getWidth(); + int height = getHeight(); + + getInsets(insets); + + int x = (width - insets.left - insets.right) / 2; + int y = (height - insets.top - insets.bottom) / 2; + + g.drawLine(insets.left + x, insets.top, insets.left + x, height - insets.bottom); + g.drawLine(insets.left, insets.top + y, width - insets.right, insets.top + y); + } + + @Override + protected void paintComponent(Graphics g) { + g.setColor(Color.BLACK); + Insets insets = getInsets(); + g.fillRect(insets.left, insets.top, getWidth() - insets.left - insets.right, + getHeight() - insets.top - insets.bottom); + } + } + + public void actionPerformed(ActionEvent event) { + if (task != null && !task.isDone()) { + return; + } + task = new GetScreenshotTask(); + task.execute(); + } + + private class GetScreenshotTask extends SwingWorker<Boolean, Void> { + private GetScreenshotTask() { + workspace.beginTask(); + } + + @Override + @WorkerThread + protected Boolean doInBackground() throws Exception { + RawImage rawImage; + try { + rawImage = device.getScreenshot(); + } catch (IOException ioe) { + return false; + } + + boolean resize = false; + isLoading = true; + try { + if (rawImage != null) { + if (image == null || rawImage.width != image.getWidth() || + rawImage.height != image.getHeight()) { + image = new BufferedImage(rawImage.width, rawImage.height, + BufferedImage.TYPE_INT_ARGB); + scanline = new int[rawImage.width]; + resize = true; + } + + switch (rawImage.bpp) { + case 16: + rawImage16toARGB(rawImage); + break; + case 32: + rawImage32toARGB(rawImage); + break; + } + } + } finally { + isLoading = false; + } + + return resize; + } + + private int getMask(int length) { + int res = 0; + for (int i = 0 ; i < length ; i++) { + res = (res << 1) + 1; + } + + return res; + } + + private void rawImage32toARGB(RawImage rawImage) { + byte[] buffer = rawImage.data; + int index = 0; + + final int redOffset = rawImage.red_offset; + final int redLength = rawImage.red_length; + final int redMask = getMask(redLength); + final int greenOffset = rawImage.green_offset; + final int greenLength = rawImage.green_length; + final int greenMask = getMask(greenLength); + final int blueOffset = rawImage.blue_offset; + final int blueLength = rawImage.blue_length; + final int blueMask = getMask(blueLength); + final int alphaLength = rawImage.alpha_length; + final int alphaOffset = rawImage.alpha_offset; + final int alphaMask = getMask(alphaLength); + + for (int y = 0 ; y < rawImage.height ; y++) { + for (int x = 0 ; x < rawImage.width ; x++) { + int value = buffer[index++] & 0x00FF; + value |= (buffer[index++] & 0x00FF) << 8; + value |= (buffer[index++] & 0x00FF) << 16; + value |= (buffer[index++] & 0x00FF) << 24; + + int r = ((value >>> redOffset) & redMask) << (8 - redLength); + int g = ((value >>> greenOffset) & greenMask) << (8 - greenLength); + int b = ((value >>> blueOffset) & blueMask) << (8 - blueLength); + int a = 0xFF; + + if (alphaLength != 0) { + a = ((value >>> alphaOffset) & alphaMask) << (8 - alphaLength); + } + + scanline[x] = a << 24 | r << 16 | g << 8 | b; + } + + image.setRGB(0, y, rawImage.width, 1, scanline, + 0, rawImage.width); + } + } + + private void rawImage16toARGB(RawImage rawImage) { + byte[] buffer = rawImage.data; + int index = 0; + + for (int y = 0 ; y < rawImage.height ; y++) { + for (int x = 0 ; x < rawImage.width ; x++) { + int value = buffer[index++] & 0x00FF; + value |= (buffer[index++] << 8) & 0x0FF00; + + int r = ((value >> 11) & 0x01F) << 3; + int g = ((value >> 5) & 0x03F) << 2; + int b = ((value ) & 0x01F) << 3; + + scanline[x] = 0xFF << 24 | r << 16 | g << 8 | b; + } + + image.setRGB(0, y, rawImage.width, 1, scanline, + 0, rawImage.width); + } + } + + @Override + protected void done() { + workspace.endTask(); + try { + if (get()) { + validate(); + crosshair.crosshair = new Point(image.getWidth() / 2, + image.getHeight() / 2); + status.showPixel(image.getWidth() / 2, image.getHeight() / 2); + loupe.moveToPoint(image.getWidth() / 2, image.getHeight() / 2); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + repaint(); + } + } + + private class OpenOverlayTask extends SwingWorker<BufferedImage, Void> { + private File file; + + private OpenOverlayTask(File file) { + this.file = file; + workspace.beginTask(); + } + + @Override + @WorkerThread + protected BufferedImage doInBackground() { + try { + return IconLoader.toCompatibleImage(ImageIO.read(file)); + } catch (IOException ex) { + ex.printStackTrace(); + } + return null; + } + + @Override + protected void done() { + try { + overlay = get(); + repaint(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } finally { + workspace.endTask(); + } + } + } +} |