Search in sources :

Example 26 with ListNumber

use of org.diirt.util.array.ListNumber in project org.csstudio.display.builder by kasemir.

the class WaveformValueDataProvider method setValue.

/**
 * Update the waveform value.
 *  @param value New value
 *  Fires event to listeners (plot)
 */
public void setValue(final VType value) {
    final ListNumber new_numbers;
    if (value instanceof VNumberArray)
        new_numbers = ((VNumberArray) value).getData();
    else
        new_numbers = new ArrayDouble(VTypeHelper.toDouble(value));
    lock.writeLock().lock();
    try {
        numbers = new_numbers;
    } finally {
        lock.writeLock().unlock();
    }
}
Also used : VNumberArray(org.diirt.vtype.VNumberArray) ListNumber(org.diirt.util.array.ListNumber) ArrayDouble(org.diirt.util.array.ArrayDouble)

Example 27 with ListNumber

use of org.diirt.util.array.ListNumber in project org.csstudio.display.builder by kasemir.

the class ImagePlot method updateImageBuffer.

/**
 * Draw all components into image buffer
 */
@Override
protected BufferedImage updateImageBuffer() {
    // Would like to use JFX WritableImage,
    // but rendering problem on Linux (sandbox.ImageScaling),
    // and no way to disable the color interpolation that 'smears'
    // the scaled image.
    // (http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8091877).
    // So image is prepared in AWT and then converted to JFX
    logger.log(Level.FINE, "updateImageBuffer");
    final Rectangle area_copy = area;
    if (area_copy.width <= 0 || area_copy.height <= 0)
        return null;
    final BufferUtil buffer = buffers.getBufferedImage(area_copy.width, area_copy.height);
    if (buffer == null)
        return null;
    final BufferedImage image = buffer.getImage();
    final Graphics2D gc = buffer.getGraphics();
    gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    gc.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
    gc.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED);
    gc.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
    // Get safe copy of the data
    // (not synchronized, i.e. width vs. data may be inconsistent,
    // but at least data won't change within this method)
    final int data_width = this.data_width, data_height = this.data_height;
    final ListNumber numbers = this.image_data;
    final boolean unsigned = this.unsigned_data;
    double min = this.min, max = this.max;
    final VImageType type = this.vimage_type;
    final ColorMappingFunction color_mapping = this.color_mapping;
    ToDoubleFunction<IteratorNumber> next_sample_func = IteratorNumber::nextDouble;
    boolean isRGB = type == VImageType.TYPE_RGB1 || type == VImageType.TYPE_RGB2 || type == VImageType.TYPE_RGB3;
    @SuppressWarnings("unchecked") final ToIntFunction<IteratorNumber>[] next_rgb = new ToIntFunction[3];
    if (numbers != null) {
        if (isRGB) {
            if (numbers instanceof ArrayShort) {
                if (unsigned) {
                    next_rgb[0] = (iter) -> getUShortForRGB(iter) << 8 & 0xFF0000;
                    next_rgb[1] = (iter) -> getUShortForRGB(iter) & 0xFF00;
                    next_rgb[2] = (iter) -> getUShortForRGB(iter) >>> 8;
                } else {
                    next_rgb[0] = (iter) -> getShortForRGB(iter) << 8 & 0xFF0000;
                    next_rgb[1] = (iter) -> getShortForRGB(iter) & 0xFF00;
                    next_rgb[2] = (iter) -> getShortForRGB(iter) >>> 8;
                }
            }
            if (numbers instanceof ArrayInt) {
                if (unsigned) {
                    next_rgb[0] = (iter) -> getUIntForRGB(iter) >>> 8 & 0xFF0000;
                    next_rgb[1] = (iter) -> getUIntForRGB(iter) >>> 16 & 0xFF00;
                    next_rgb[2] = (iter) -> getUIntForRGB(iter) >>> 24;
                } else {
                    next_rgb[0] = (iter) -> getIntForRGB(iter) >>> 8 & 0xFF0000;
                    next_rgb[1] = (iter) -> getIntForRGB(iter) >>> 16 & 0xFF00;
                    next_rgb[2] = (iter) -> getIntForRGB(iter) >>> 24;
                }
            } else {
                if (!(numbers instanceof ArrayByte))
                    logger.log(Level.WARNING, "Cannot handle rgb1 image data of type " + numbers.getClass().getName());
                if (unsigned) {
                    next_rgb[0] = (iter) -> getUByteForRGB(iter) << 16;
                    next_rgb[1] = (iter) -> getUByteForRGB(iter) << 8;
                    next_rgb[2] = (iter) -> getUByteForRGB(iter);
                } else {
                    next_rgb[0] = (iter) -> getByteForRGB(iter) << 16;
                    next_rgb[1] = (iter) -> getByteForRGB(iter) << 8;
                    next_rgb[2] = (iter) -> getByteForRGB(iter);
                }
            }
        } else // is not RGB
        {
            if (unsigned) {
                if (numbers instanceof ArrayShort)
                    next_sample_func = ImagePlot::getUnsignedShort;
                else if (numbers instanceof ArrayByte)
                    next_sample_func = ImagePlot::getUnsignedByte;
                else if (numbers instanceof ArrayInt)
                    next_sample_func = ImagePlot::getUnsignedInt;
                else
                    logger.log(Level.WARNING, "Cannot handle unsigned data of type " + numbers.getClass().getName());
            }
            if (autoscale) {
                // Compute min..max before layout of color bar
                final IteratorNumber iter = numbers.iterator();
                min = Double.MAX_VALUE;
                max = Double.NEGATIVE_INFINITY;
                while (iter.hasNext()) {
                    final double sample = next_sample_func.applyAsDouble(iter);
                    if (sample > max)
                        max = sample;
                    if (sample < min)
                        min = sample;
                }
                logger.log(Level.FINE, "Autoscale range {0} .. {1}", new Object[] { min, max });
            }
        }
    }
    // If log, min needs to be 1
    if (colorbar_axis.isLogarithmic() && min < 1.0)
        min = 1;
    colorbar_axis.setValueRange(min, max);
    if (need_layout.getAndSet(false))
        computeLayout(gc, area_copy, min, max);
    // Fill with a 'background' color
    gc.setColor(background);
    gc.fillRect(0, 0, area_copy.width, area_copy.height);
    if (numbers != null) {
        // Paint the image
        gc.setClip(image_area.x, image_area.y, image_area.width, image_area.height);
        final Object image_or_error = !isRGB ? drawData(data_width, data_height, numbers, next_sample_func, min, max, color_mapping) : drawDataRGB(data_width, data_height, numbers, next_rgb, type);
        if (image_or_error instanceof BufferedImage) {
            final BufferedImage unscaled = (BufferedImage) image_or_error;
            // Transform from full axis range into data range,
            // using the current 'zoom' state of each axis
            final LinearScreenTransform t = new LinearScreenTransform();
            AxisRange<Double> zoomed = x_axis.getValueRange();
            t.config(min_x, max_x, 0, data_width);
            // Round down .. up to always cover the image_area
            final int src_x1 = Math.max(0, (int) t.transform(zoomed.getLow()));
            final int src_x2 = Math.min(data_width, (int) (t.transform(zoomed.getHigh()) + 1));
            // Pixels of the image need to be aligned to their axis location,
            // especially when zoomed way in and the pixels are huge.
            // Turn pixel back into axis value, and then determine its destination on screen.
            final int dst_x1 = x_axis.getScreenCoord(t.inverse(src_x1));
            final int dst_x2 = x_axis.getScreenCoord(t.inverse(src_x2));
            // For Y axis, min_y == bottom == data_height
            zoomed = y_axis.getValueRange();
            t.config(min_y, max_y, data_height, 0);
            final int src_y1 = Math.max(0, (int) t.transform(zoomed.getHigh()));
            final int src_y2 = Math.min(data_height, (int) (t.transform(zoomed.getLow()) + 1));
            final int dst_y1 = y_axis.getScreenCoord(t.inverse(src_y1));
            final int dst_y2 = y_axis.getScreenCoord(t.inverse(src_y2));
            switch(interpolation) {
                case NONE:
                    gc.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
                    break;
                case INTERPOLATE:
                    gc.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                    break;
                default:
                    // If image is smaller than screen area, show the actual pixels
                    if ((src_x2 - src_x1) < image_area.width && (src_y2 - src_y1) < image_area.height)
                        gc.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
                    else
                        // If image is larger than screen area, use best possible interpolation
                        // to avoid artifacts from statistically picking some specific nearest neighbor
                        gc.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            }
            gc.drawImage(unscaled, dst_x1, dst_y1, dst_x2, dst_y2, src_x1, src_y1, src_x2, src_y2, /* ImageObserver */
            null);
        } else {
            gc.setColor(Color.RED);
            gc.setFont(x_axis.label_font);
            gc.drawString(Objects.toString(image_or_error), image_area.x + 10, image_area.y + 20);
        }
        gc.setClip(0, 0, area_copy.width, area_copy.height);
    }
    // Axes
    y_axis.paint(gc, image_area);
    x_axis.paint(gc, image_area);
    // Color bar
    if (colorbar_area != null) {
        final BufferedImage bar = drawColorBar(min, max, color_mapping);
        gc.drawImage(bar, colorbar_area.x, colorbar_area.y, colorbar_area.width, colorbar_area.height, null);
        colorbar_axis.paint(gc, colorbar_area);
    }
    // ROI uses X axis font
    gc.setFont(x_axis.label_font);
    for (RegionOfInterest roi : rois) drawROI(gc, roi);
    return image;
}
Also used : RegionOfInterest(org.csstudio.javafx.rtplot.RegionOfInterest) ColorMappingFunction(org.csstudio.javafx.rtplot.ColorMappingFunction) Rectangle(java.awt.Rectangle) LinearScreenTransform(org.csstudio.javafx.rtplot.internal.util.LinearScreenTransform) BufferedImage(java.awt.image.BufferedImage) Graphics2D(java.awt.Graphics2D) ListNumber(org.diirt.util.array.ListNumber) BufferUtil(org.csstudio.javafx.BufferUtil) VImageType(org.diirt.vtype.VImageType) ToIntFunction(java.util.function.ToIntFunction) ArrayByte(org.diirt.util.array.ArrayByte) ArrayInt(org.diirt.util.array.ArrayInt) ArrayShort(org.diirt.util.array.ArrayShort) IteratorNumber(org.diirt.util.array.IteratorNumber)

Example 28 with ListNumber

use of org.diirt.util.array.ListNumber in project org.csstudio.display.builder by kasemir.

the class FormatOptionHandler method getLongString.

/**
 * @param value Array of numbers
 *  @return String based on character for each array element
 */
private static String getLongString(final VNumberArray value) {
    final ListNumber data = value.getData();
    final byte[] bytes = new byte[data.size()];
    // Copy bytes until end or '\0'
    int len = 0;
    while (len < bytes.length) {
        final byte b = data.getByte(len);
        if (b == 0)
            break;
        else
            bytes[len++] = b;
    }
    // Use actual 'len', not data.size()
    return new String(bytes, 0, len, UTF8);
}
Also used : ListNumber(org.diirt.util.array.ListNumber) VString(org.diirt.vtype.VString)

Example 29 with ListNumber

use of org.diirt.util.array.ListNumber in project org.csstudio.display.builder by kasemir.

the class FormatOptionHandler method format.

/**
 * Format value as string
 *
 *  @param value Value to format
 *  @param option How to format the value
 *  @param precision Precision to use. -1 will try to fetch precision from VType
 *  @param show_units Include units?
 *  @return Formatted value
 */
public static String format(final VType value, final FormatOption option, int precision, final boolean show_units) {
    precision = actualPrecision(value, precision);
    if (value == null)
        return "<null>";
    if (value instanceof VNumber) {
        final VNumber number = (VNumber) value;
        final String text = formatNumber(number.getValue(), number, option, precision);
        if (show_units && !number.getUnits().isEmpty())
            return text + " " + number.getUnits();
        return text;
    } else if (value instanceof VString)
        return ((VString) value).getValue();
    else if (value instanceof VEnum)
        return formatEnum((VEnum) value, option);
    else if (value instanceof VNumberArray) {
        final VNumberArray array = (VNumberArray) value;
        if (option == FormatOption.STRING)
            return getLongString(array);
        final ListNumber data = array.getData();
        if (data.size() <= 0)
            return "[]";
        final StringBuilder buf = new StringBuilder("[");
        buf.append(formatNumber(data.getDouble(0), array, option, precision));
        for (int i = 1; i < data.size(); ++i) {
            buf.append(", ");
            buf.append(formatNumber(data.getDouble(i), array, option, precision));
        }
        buf.append("]");
        if (show_units && !array.getUnits().isEmpty())
            buf.append(" ").append(array.getUnits());
        return buf.toString();
    } else if (value instanceof VEnumArray) {
        final List<String> labels = ((VEnumArray) value).getLabels();
        final StringBuilder buf = new StringBuilder("[");
        for (int i = 0; i < labels.size(); ++i) {
            if (i > 0)
                buf.append(", ");
            buf.append(labels.get(i));
        }
        buf.append("]");
        return buf.toString();
    } else if (value instanceof VStringArray)
        return StringList.join(((VStringArray) value).getData());
    else if (value instanceof VImage) {
        final VImage image = (VImage) value;
        return "VImage(" + image.getWidth() + " x " + image.getHeight() + ")";
    } else if (value instanceof VTable)
        return formatTable((VTable) value);
    return "<" + value.getClass().getName() + ">";
}
Also used : VEnumArray(org.diirt.vtype.VEnumArray) VNumber(org.diirt.vtype.VNumber) VString(org.diirt.vtype.VString) VEnum(org.diirt.vtype.VEnum) VNumberArray(org.diirt.vtype.VNumberArray) ListNumber(org.diirt.util.array.ListNumber) VString(org.diirt.vtype.VString) VTable(org.diirt.vtype.VTable) VStringArray(org.diirt.vtype.VStringArray) VImage(org.diirt.vtype.VImage)

Aggregations

ListNumber (org.diirt.util.array.ListNumber)29 VNumberArray (org.diirt.vtype.VNumberArray)13 List (java.util.List)10 VString (org.diirt.vtype.VString)9 ArrayList (java.util.ArrayList)6 ArrayDouble (org.diirt.util.array.ArrayDouble)5 ArrayInt (org.diirt.util.array.ArrayInt)5 ListInt (org.diirt.util.array.ListInt)5 VEnumArray (org.diirt.vtype.VEnumArray)5 VNumber (org.diirt.vtype.VNumber)4 VTable (org.diirt.vtype.VTable)4 VType (org.diirt.vtype.VType)4 Test (org.junit.Test)4 AbstractList (java.util.AbstractList)3 ListDouble (org.diirt.util.array.ListDouble)3 VEnum (org.diirt.vtype.VEnum)3 VStringArray (org.diirt.vtype.VStringArray)3 BufferedImage (java.awt.image.BufferedImage)2 Background (javafx.scene.layout.Background)2 BackgroundFill (javafx.scene.layout.BackgroundFill)2