OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [awt/] [image/] [PixelGrabber.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* PixelGrabber.java -- retrieve a subset of an image's data
2
   Copyright (C) 1999, 2003, 2004  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package java.awt.image;
40
 
41
import java.awt.Image;
42
import java.util.Hashtable;
43
 
44
/**
45
 * PixelGrabber is an ImageConsumer that extracts a rectangular region
46
 * of pixels from an Image.
47
 */
48
public class PixelGrabber implements ImageConsumer
49
{
50
  int x, y, offset;
51
  int width = -1;
52
  int height = -1;
53
  int scansize = -1;
54
  boolean forceRGB = true;
55
 
56
  ColorModel model = ColorModel.getRGBdefault();
57
  int hints;
58
  Hashtable<?,?> props;
59
 
60
  int int_pixel_buffer[];
61
  boolean ints_delivered = false;
62
  byte byte_pixel_buffer[];
63
  boolean bytes_delivered = false;
64
 
65
  ImageProducer ip;
66
  int observerStatus;
67
  int consumerStatus;
68
 
69
  private Thread grabberThread;
70
  boolean grabbing = false;
71
 
72
  /**
73
   * Construct a PixelGrabber that will retrieve RGB data from a given
74
   * Image.
75
   *
76
   * The RGB data will be retrieved from a rectangular region
77
   * <code>(x, y, w, h)</code> within the image.  The data will be
78
   * stored in the provided <code>pix</code> array, which must have
79
   * been initialized to a size of at least <code>w * h</code>.  The
80
   * data for a pixel (m, n) in the grab rectangle will be stored at
81
   * <code>pix[(n - y) * scansize + (m - x) + off]</code>.
82
   *
83
   * @param img the Image from which to grab pixels
84
   * @param x the x coordinate, relative to <code>img</code>'s
85
   * top-left corner, of the grab rectangle's top-left pixel
86
   * @param y the y coordinate, relative to <code>img</code>'s
87
   * top-left corner, of the grab rectangle's top-left pixel
88
   * @param w the width of the grab rectangle, in pixels
89
   * @param h the height of the grab rectangle, in pixels
90
   * @param pix the array in which to store grabbed RGB pixel data
91
   * @param off the offset into the <code>pix</code> array at which to
92
   * start storing RGB data
93
   * @param scansize a set of <code>scansize</code> consecutive
94
   * elements in the <code>pix</code> array represents one row of
95
   * pixels in the grab rectangle
96
   */
97
  public PixelGrabber(Image img, int x, int y, int w, int h,
98
                      int pix[], int off, int scansize)
99
  {
100
    this (img.getSource(), x, y, w, h, pix, off, scansize);
101
  }
102
 
103
  /**
104
   * Construct a PixelGrabber that will retrieve RGB data from a given
105
   * ImageProducer.
106
   *
107
   * The RGB data will be retrieved from a rectangular region
108
   * <code>(x, y, w, h)</code> within the image produced by
109
   * <code>ip</code>.  The data will be stored in the provided
110
   * <code>pix</code> array, which must have been initialized to a
111
   * size of at least <code>w * h</code>.  The data for a pixel (m, n)
112
   * in the grab rectangle will be stored at
113
   * <code>pix[(n - y) * scansize + (m - x) + off]</code>.
114
   *
115
   * @param ip the ImageProducer from which to grab pixels. This can
116
   * be null.
117
   * @param x the x coordinate of the grab rectangle's top-left pixel,
118
   * specified relative to the top-left corner of the image produced
119
   * by <code>ip</code>
120
   * @param y the y coordinate of the grab rectangle's top-left pixel,
121
   * specified relative to the top-left corner of the image produced
122
   * by <code>ip</code>
123
   * @param w the width of the grab rectangle, in pixels
124
   * @param h the height of the grab rectangle, in pixels
125
   * @param pix the array in which to store grabbed RGB pixel data
126
   * @param off the offset into the <code>pix</code> array at which to
127
   * start storing RGB data
128
   * @param scansize a set of <code>scansize</code> consecutive
129
   * elements in the <code>pix</code> array represents one row of
130
   * pixels in the grab rectangle
131
   */
132
  public PixelGrabber(ImageProducer ip, int x, int y, int w, int h,
133
                      int pix[], int off, int scansize)
134
  {
135
    this.ip = ip;
136
    this.x = x;
137
    this.y = y;
138
    this.width = w;
139
    this.height = h;
140
    this.offset = off;
141
    this.scansize = scansize;
142
 
143
    int_pixel_buffer = pix;
144
    // Initialize the byte array in case ip sends us byte-formatted
145
    // pixel data.
146
    byte_pixel_buffer = new byte[pix.length * 4];
147
  }
148
 
149
  /**
150
   * Construct a PixelGrabber that will retrieve data from a given
151
   * Image.
152
   *
153
   * The RGB data will be retrieved from a rectangular region
154
   * <code>(x, y, w, h)</code> within the image.  The data will be
155
   * stored in an internal array which can be accessed by calling
156
   * <code>getPixels</code>.  The data for a pixel (m, n) in the grab
157
   * rectangle will be stored in the returned array at index
158
   * <code>(n - y) * scansize + (m - x) + off</code>.
159
   * If forceRGB is false, then the returned data will be not be
160
   * converted to RGB from its format in <code>img</code>.
161
   *
162
   * If <code>w</code> is negative, the width of the grab region will
163
   * be from x to the right edge of the image.  Likewise, if
164
   * <code>h</code> is negative, the height of the grab region will be
165
   * from y to the bottom edge of the image.
166
   *
167
   * @param img the Image from which to grab pixels
168
   * @param x the x coordinate, relative to <code>img</code>'s
169
   * top-left corner, of the grab rectangle's top-left pixel
170
   * @param y the y coordinate, relative to <code>img</code>'s
171
   * top-left corner, of the grab rectangle's top-left pixel
172
   * @param w the width of the grab rectangle, in pixels
173
   * @param h the height of the grab rectangle, in pixels
174
   * @param forceRGB true to force conversion of the rectangular
175
   * region's pixel data to RGB
176
   */
177
  public PixelGrabber(Image img,
178
                      int x, int y,
179
                      int w, int h,
180
                      boolean forceRGB)
181
  {
182
    this.ip = img.getSource();
183
 
184
    if (this.ip == null)
185
      throw new NullPointerException("The ImageProducer must not be null.");
186
 
187
    this.x = x;
188
    this.y = y;
189
    width = w;
190
    height = h;
191
    // If width or height is negative, postpone pixel buffer
192
    // initialization until setDimensions is called back by ip.
193
    if (width >= 0 && height >= 0)
194
      {
195
        int_pixel_buffer = new int[width * height];
196
        byte_pixel_buffer = new byte[width * height];
197
      }
198
    this.forceRGB = forceRGB;
199
  }
200
 
201
  /**
202
   * Start grabbing pixels.
203
   *
204
   * Spawns an image production thread that calls back to this
205
   * PixelGrabber's ImageConsumer methods.
206
   */
207
  public synchronized void startGrabbing()
208
  {
209
    // Make sure we're not already grabbing.
210
    if (grabbing == false)
211
      {
212
        grabbing = true;
213
        grabberThread = new Thread ()
214
          {
215
            public void run ()
216
            {
217
              try
218
                {
219
                  ip.startProduction (PixelGrabber.this);
220
                }
221
              catch (Exception ex)
222
                {
223
                  imageComplete(ImageConsumer.IMAGEABORTED);
224
                }
225
            }
226
          };
227
        grabberThread.start ();
228
      }
229
  }
230
 
231
  /**
232
   * Abort pixel grabbing.
233
   */
234
  public synchronized void abortGrabbing()
235
  {
236
    if (grabbing)
237
      {
238
        // Interrupt the grabbing thread.
239
        Thread moribund = grabberThread;
240
        grabberThread = null;
241
        moribund.interrupt();
242
 
243
        imageComplete (ImageConsumer.IMAGEABORTED);
244
      }
245
  }
246
 
247
  /**
248
   * Have our Image or ImageProducer start sending us pixels via our
249
   * ImageConsumer methods and wait for all pixels in the grab
250
   * rectangle to be delivered.
251
   *
252
   * @return true if successful, false on abort or error
253
   *
254
   * @throws InterruptedException if interrupted by another thread.
255
   */
256
  public synchronized boolean grabPixels() throws InterruptedException
257
  {
258
    return grabPixels(0);
259
  }
260
 
261
  /**
262
   * grabPixels's behavior depends on the value of <code>ms</code>.
263
   *
264
   * If ms < 0, return true if all pixels from the source image have
265
   * been delivered, false otherwise.  Do not wait.
266
   *
267
   * If ms >= 0 then we request that our Image or ImageProducer start
268
   * delivering pixels to us via our ImageConsumer methods.
269
   *
270
   * If ms > 0, wait at most <code>ms</code> milliseconds for
271
   * delivery of all pixels within the grab rectangle.
272
   *
273
   * If ms == 0, wait until all pixels have been delivered.
274
   *
275
   * @return true if all pixels from the source image have been
276
   * delivered, false otherwise
277
   *
278
   * @throws InterruptedException if this thread is interrupted while
279
   * we are waiting for pixels to be delivered
280
   */
281
  public synchronized boolean grabPixels(long ms) throws InterruptedException
282
  {
283
    if (ms < 0)
284
      return ((observerStatus & (ImageObserver.FRAMEBITS
285
                                 | ImageObserver.ALLBITS)) != 0);
286
 
287
    // Spawn a new ImageProducer thread to send us the image data via
288
    // our ImageConsumer methods.
289
    startGrabbing();
290
 
291
    if (ms > 0)
292
      {
293
        long stop_time = System.currentTimeMillis() + ms;
294
        long time_remaining;
295
        while (grabbing)
296
          {
297
            time_remaining = stop_time - System.currentTimeMillis();
298
            if (time_remaining <= 0)
299
              break;
300
            wait (time_remaining);
301
          }
302
        abortGrabbing ();
303
      }
304
    else
305
      wait ();
306
 
307
    // If consumerStatus is non-zero then the image is done loading or
308
    // an error has occurred.
309
    if (consumerStatus != 0)
310
      return setObserverStatus ();
311
 
312
    return ((observerStatus & (ImageObserver.FRAMEBITS
313
                               | ImageObserver.ALLBITS)) != 0);
314
  }
315
 
316
  // Set observer status flags based on the current consumer status
317
  // flags.  Return true if the consumer flags indicate that the
318
  // image was loaded successfully, or false otherwise.
319
  private synchronized boolean setObserverStatus ()
320
  {
321
    boolean retval = false;
322
 
323
    if ((consumerStatus & IMAGEERROR) != 0)
324
      observerStatus |= ImageObserver.ERROR;
325
 
326
    if ((consumerStatus & IMAGEABORTED) != 0)
327
      observerStatus |= ImageObserver.ABORT;
328
 
329
    if ((consumerStatus & STATICIMAGEDONE) != 0)
330
      {
331
        observerStatus |= ImageObserver.ALLBITS;
332
        retval = true;
333
      }
334
 
335
    if ((consumerStatus & SINGLEFRAMEDONE) != 0)
336
      {
337
        observerStatus |= ImageObserver.FRAMEBITS;
338
        retval = true;
339
      }
340
 
341
    return retval;
342
  }
343
 
344
  /**
345
   * @return the status of the pixel grabbing thread, represented by a
346
   * bitwise OR of ImageObserver flags
347
   */
348
  public synchronized int getStatus()
349
  {
350
    return observerStatus;
351
  }
352
 
353
  /**
354
   * @return the width of the grab rectangle in pixels, or a negative
355
   * number if the ImageProducer has not yet called our setDimensions
356
   * method
357
   */
358
  public synchronized int getWidth()
359
  {
360
    return width;
361
  }
362
 
363
  /**
364
   * @return the height of the grab rectangle in pixels, or a negative
365
   * number if the ImageProducer has not yet called our setDimensions
366
   * method
367
   */
368
  public synchronized int getHeight()
369
  {
370
    return height;
371
  }
372
 
373
  /**
374
   * @return a byte array of pixel data if ImageProducer delivered
375
   * pixel data using the byte[] variant of setPixels, or an int array
376
   * otherwise
377
   */
378
  public synchronized Object getPixels()
379
  {
380
    if (ints_delivered)
381
      return int_pixel_buffer;
382
    else if (bytes_delivered)
383
      return byte_pixel_buffer;
384
    else
385
      return null;
386
  }
387
 
388
  /**
389
   * @return the ColorModel currently being used for the majority of
390
   * pixel data conversions
391
   */
392
  public synchronized ColorModel getColorModel()
393
  {
394
    return model;
395
  }
396
 
397
  /**
398
   * Our <code>ImageProducer</code> calls this method to indicate the
399
   * size of the image being produced.
400
   *
401
   * setDimensions is an ImageConsumer method.  None of PixelGrabber's
402
   * ImageConsumer methods should be called by code that instantiates
403
   * a PixelGrabber.  They are only made public so they can be called
404
   * by the PixelGrabber's ImageProducer.
405
   *
406
   * @param width the width of the image
407
   * @param height the height of the image
408
   */
409
  public synchronized void setDimensions(int width, int height)
410
  {
411
    // Our width wasn't set when we were constructed.  Set our width
412
    // so that the grab region includes all pixels from x to the right
413
    // edge of the source image.
414
    if (this.width < 0)
415
      this.width = width - x;
416
 
417
    // Our height wasn't set when we were constructed.  Set our height
418
    // so that the grab region includes all pixels from y to the
419
    // bottom edge of the source image.
420
    if (this.height < 0)
421
      this.height = height - y;
422
 
423
    if (scansize < 0)
424
      scansize = this.width;
425
 
426
    if (int_pixel_buffer == null)
427
      int_pixel_buffer = new int[this.width * this.height];
428
 
429
    if (byte_pixel_buffer == null)
430
      byte_pixel_buffer = new byte[this.width * this.height];
431
  }
432
 
433
  /**
434
   * Our <code>ImageProducer</code> may call this method to send us a
435
   * list of its image's properties.
436
   *
437
   * setProperties is an ImageConsumer method.  None of PixelGrabber's
438
   * ImageConsumer methods should be called by code that instantiates
439
   * a PixelGrabber.  They are only made public so they can be called
440
   * by the PixelGrabber's ImageProducer.
441
   *
442
   * @param props a list of properties associated with the image being
443
   * produced
444
   */
445
  public synchronized void setProperties(Hashtable<?,?> props)
446
  {
447
    this.props = props;
448
  }
449
 
450
  /**
451
   * Our ImageProducer will call <code>setColorModel</code> to
452
   * indicate the model used by the majority of calls to
453
   * <code>setPixels</code>.  Each call to <code>setPixels</code>
454
   * could however indicate a different <code>ColorModel</code>.
455
   *
456
   * setColorModel is an ImageConsumer method.  None of PixelGrabber's
457
   * ImageConsumer methods should be called by code that instantiates
458
   * a PixelGrabber.  They are only made public so they can be called
459
   * by the PixelGrabber's ImageProducer.
460
   *
461
   * @param model the color model to be used most often by setPixels
462
   *
463
   * @see ColorModel
464
   */
465
  public synchronized void setColorModel(ColorModel model)
466
  {
467
    this.model = model;
468
  }
469
 
470
  /**
471
   * Our <code>ImageProducer</code> may call this method with a
472
   * bit mask of hints from any of <code>RANDOMPIXELORDER</code>,
473
   * <code>TOPDOWNLEFTRIGHT</code>, <code>COMPLETESCANLINES</code>,
474
   * <code>SINGLEPASS</code>, <code>SINGLEFRAME</code>.
475
   *
476
   * setHints is an ImageConsumer method.  None of PixelGrabber's
477
   * ImageConsumer methods should be called by code that instantiates
478
   * a PixelGrabber.  They are only made public so they can be called
479
   * by the PixelGrabber's ImageProducer.
480
   *
481
   * @param flags a bit mask of hints
482
   */
483
  public synchronized void setHints(int flags)
484
  {
485
    hints = flags;
486
  }
487
 
488
  /**
489
   * Our ImageProducer calls setPixels to deliver a subset of its
490
   * pixels.
491
   *
492
   * Each element of the pixels array represents one pixel.  The
493
   * pixel data is formatted according to the color model model.
494
   * The x and y parameters are the coordinates of the rectangular
495
   * region of pixels being delivered to this ImageConsumer,
496
   * specified relative to the top left corner of the image being
497
   * produced.  Likewise, w and h are the pixel region's dimensions.
498
   *
499
   * @param x x coordinate of pixel block
500
   * @param y y coordinate of pixel block
501
   * @param w width of pixel block
502
   * @param h height of pixel block
503
   * @param model color model used to interpret pixel data
504
   * @param pixels pixel block data
505
   * @param offset offset into pixels array
506
   * @param scansize width of one row in the pixel block
507
   */
508
  public synchronized void setPixels(int x, int y, int w, int h,
509
                                     ColorModel model, byte[] pixels,
510
                                     int offset, int scansize)
511
  {
512
    ColorModel currentModel;
513
    if (model != null)
514
      currentModel = model;
515
    else
516
      currentModel = this.model;
517
 
518
    for(int yp = y; yp < (y + h); yp++)
519
      {
520
        for(int xp = x; xp < (x + w); xp++)
521
          {
522
            // Check if the coordinates (xp, yp) are within the
523
            // pixel block that we are grabbing.
524
            if(xp >= this.x
525
               && yp >= this.y
526
               && xp < (this.x + this.width)
527
               && yp < (this.y + this.height))
528
              {
529
                int i = (yp - this.y) * this.scansize + (xp - this.x) + this.offset;
530
                int p = (yp - y) * scansize + (xp - x) + offset;
531
                if (forceRGB)
532
                  {
533
                    ints_delivered = true;
534
 
535
                    int_pixel_buffer[i] = currentModel.getRGB (pixels[p] & 0xFF);
536
                  }
537
                else
538
                  {
539
                    bytes_delivered = true;
540
 
541
                    byte_pixel_buffer[i] = pixels[p];
542
                  }
543
              }
544
          }
545
      }
546
  }
547
 
548
  /**
549
   * Our ImageProducer calls setPixels to deliver a subset of its
550
   * pixels.
551
   *
552
   * Each element of the pixels array represents one pixel.  The
553
   * pixel data is formatted according to the color model model.
554
   * The x and y parameters are the coordinates of the rectangular
555
   * region of pixels being delivered to this ImageConsumer,
556
   * specified relative to the top left corner of the image being
557
   * produced.  Likewise, w and h are the pixel region's dimensions.
558
   *
559
   * @param x x coordinate of pixel block
560
   * @param y y coordinate of pixel block
561
   * @param w width of pixel block
562
   * @param h height of pixel block
563
   * @param model color model used to interpret pixel data
564
   * @param pixels pixel block data
565
   * @param offset offset into pixels array
566
   * @param scansize width of one row in the pixel block
567
   */
568
  public synchronized void setPixels(int x, int y, int w, int h,
569
                                     ColorModel model, int[] pixels,
570
                                     int offset, int scansize)
571
  {
572
    ColorModel currentModel;
573
    if (model != null)
574
      currentModel = model;
575
    else
576
      currentModel = this.model;
577
 
578
    ints_delivered = true;
579
 
580
    for(int yp = y; yp < (y + h); yp++)
581
      {
582
        for(int xp = x; xp < (x + w); xp++)
583
          {
584
            // Check if the coordinates (xp, yp) are within the
585
            // pixel block that we are grabbing.
586
            if(xp >= this.x
587
               && yp >= this.y
588
               && xp < (this.x + this.width)
589
               && yp < (this.y + this.height))
590
              {
591
                int i = (yp - this.y) * this.scansize + (xp - this.x) + this.offset;
592
                int p = (yp - y) * scansize + (xp - x) + offset;
593
                if (forceRGB)
594
                  int_pixel_buffer[i] = currentModel.getRGB (pixels[p]);
595
                else
596
                  int_pixel_buffer[i] = pixels[p];
597
              }
598
          }
599
      }
600
  }
601
 
602
  /**
603
   * Our <code>ImageProducer</code> calls this method to inform us
604
   * that a single frame or the entire image is complete.  The method
605
   * is also used to inform us of an error in loading or producing the
606
   * image.
607
   *
608
   * @param status the status of image production, represented by a
609
   * bitwise OR of ImageConsumer flags
610
   */
611
  public synchronized void imageComplete(int status)
612
  {
613
    consumerStatus = status;
614
    setObserverStatus ();
615
    grabbing = false;
616
    if (ip != null)
617
      ip.removeConsumer (this);
618
 
619
    notifyAll ();
620
  }
621
 
622
  /**
623
   * @return the return value of getStatus
624
   *
625
   * @specnote The newer getStatus should be used in place of status.
626
   */
627
  public synchronized int status()
628
  {
629
    return getStatus();
630
  }
631
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.