Statistics
| Revision:

root / trunk / libraries / libCresques / src / org / cresques / io / EcwFile.java @ 13173

History | View | Annotate | Download (37.5 KB)

1
/*
2
 * Cresques Mapping Suite. Graphic Library for constructing mapping applications.
3
 *
4
 * Copyright (C) 2004-5.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 *
20
 * For more information, contact:
21
 *
22
 * cresques@gmail.com
23
 */
24
package org.cresques.io;
25

    
26
import java.awt.Dimension;
27
import java.awt.Image;
28
import java.awt.Point;
29
import java.awt.image.BufferedImage;
30
import java.awt.image.PixelGrabber;
31
import java.io.File;
32

    
33
import org.cresques.cts.ICoordTrans;
34
import org.cresques.cts.IProjection;
35
import org.cresques.px.Extent;
36

    
37
import com.ermapper.ecw.JNCSFile;
38
import com.ermapper.ecw.JNCSFileNotOpenException;
39
import com.ermapper.ecw.JNCSInvalidSetViewException;
40
import com.ermapper.ecw.JNCSProgressiveUpdate;
41
import com.ermapper.util.JNCSDatasetPoint;
42
import com.ermapper.util.JNCSWorldPoint;
43

    
44

    
45
/**
46
 * Soporte para los ficheros .ecw de ErMapper.
47
 * <br>
48
 * NOTA: El SDK que ermapper ha puesto a disposici?n del p?blico en java
49
 * es una versi?n 2.45, de 19/11/2001. Est? implementada usando JNI que
50
 * se apoya en tres librer?as din?micas (dll), y presenta deficiencias
51
 * muy graves a la hora de acceder a la informaci?n. Hasta el momento
52
 * hemos detectado 3 de ellas:<BR>
53
 *     1?.- No soporta ampliaciones superiores a 1:1. si se intenta acceder
54
 * a un ecw con un zoom mayor da una excepci?n del tipo
55
 * com.ermapper.ecw.JNCSInvalidSetViewException, que de no ser tenida encuenta
56
 * acaba tirando abajo la m?quina virtual de java.<BR>
57
 *     2?.- La longitud m?xima de l?nea que adminte el m?todo readLineRGBA es
58
 * de unos 2500 pixeles, lo que hace el uso para la impresi?n en formatos
59
 * superiorea a A4 a 300 ppp o m?s inviable.<BR>
60
 *     3?.- La actualizaci?n progresiva usando el interface JNCSProgressiveUpdate
61
 * con el JNCSFile hace que el equipo genere un error severo y se apague. Este
62
 * error imposibilita esta t?cnica de acceso a ECW.<BR>
63
 * <br>
64
 * Para saltarnos la limitaci?n del bug#1 pedimos la ventana correspondiente al zoom 1:1 para
65
 * el view que nos han puesto, y la resizeamos al tama?o que nos pide el usuario.<br>
66
 * Como consecuencia del bug#2, para tama?os de ventana muy grandes (los necesarios
67
 * para imprimir a m?s de A4 a 300DPI), hay que hacer varias llamadas al fichero con
68
 * varios marcos contiguos, y los devolvemos 'pegados' en una sola imagen (esto se
69
 * realiza de manera transparente para el usuario dentro de la llamada a updateImage.<br>
70
 *
71
 * @author "Luis W. Sevilla" <sevilla_lui@gva.es>
72
 */
73
public class EcwFile extends GeoRasterFile implements JNCSProgressiveUpdate {
74
                //Lleva la cuenta del n?mero de actualizaciones que se hace de una imagen que corresponde con el
75
                //n?mero de bandas que tiene. Esto es necesario ya que si una imagen tiene el mustResize a
76
                //true solo debe llamar a la funci?n resizeImage al actualizar la ?ltima banda, sino al hacer
77
                //un zoom menor que 1:1 se veria mal
78
                private static int nUpdate = 0;
79
                private JNCSFile file = null;
80
                private String errorMessage = null;
81
                private boolean multifile = false;
82
                private Extent v = null;
83

    
84

    
85
                // Ultimo porcentaje de refresco. Se carga en el update y se
86
                // actualiza en el refreshUpdate
87
                private int lastRefreshPercent = 0;
88

    
89
                public EcwFile(IProjection proj, String fName) {
90
                                super(proj, null);
91
                                fName = DataSourceSE.normalize(fName);
92
                                super.setName(fName);
93
                                extent = new Extent();
94

    
95
                                try {
96

    
97
                                        if (!new File(fName).exists() && !fName.startsWith("ecwp:")){
98
                                                System.err.println("No se puede abrir el archivo");
99
                                                return;
100
                                        }
101

    
102
                                                file = new JNCSFile(fName, false);
103
                                        load();
104
                                                //readGeoInfo(fName);
105
                                                bandCount = file.numBands;
106

    
107
                                                if ( bandCount > 2) {
108
                                                                                setBand(RED_BAND,   0);
109
                                                                                setBand(GREEN_BAND, 1);
110
                                                                                setBand(BLUE_BAND,  2);
111
                                                } else
112
                                                                                setBand(RED_BAND|GREEN_BAND|BLUE_BAND, 0);
113
                                } catch (Exception e) {
114
                                                errorMessage = e.getMessage();
115
                                                System.err.println(errorMessage);
116
                                                e.printStackTrace();
117
                                }
118
                }
119

    
120
                /**
121
                 * Carga un ECW.
122
                 *
123
                 * @param fname
124
                 */
125
                public GeoFileSE load() {
126
                                double minX;
127
                                double minY;
128
                                double maxX;
129
                                double maxY;
130

    
131
                                if(file.cellIncrementY > 0)
132
                                        file.cellIncrementY = -file.cellIncrementY;
133

    
134
                                minX = file.originX;
135
                                maxY = file.originY;
136
                                maxX = file.originX +
137
                                                         ((double) (file.width - 1) * file.cellIncrementX);
138
                                minY = file.originY +
139
                                                         ((double) (file.height - 1) * file.cellIncrementY);
140

    
141
                                extent = new Extent(minX, minY, maxX, maxY);
142
                                requestExtent = extent;
143
                                return this;
144
                }
145

    
146
                public void close() {
147
                        if(file != null){
148
                                file.close(true);
149
                                file = null;
150
                        }
151
                }
152

    
153
                /**
154
                 * Devuelve el ancho de la imagen
155
                 */
156
                public int getWidth() {
157
                                return file.width;
158
                }
159

    
160
                /**
161
                 * Devuelve el alto de la imagen
162
                 */
163
                public int getHeight() {
164
                                return file.height;
165
                }
166

    
167
                /**
168
                 *
169
                 */
170
                public void setMultifile(boolean mult) {
171
                                this.multifile = mult;
172
                }
173

    
174
                public void setView(Extent e) {
175
                        //Aplicamos la transformaci?n a la vista en caso de que haya un fichero .rmf
176
                        /*
177
                        if(file.cellIncrementY > 0)
178
                                        file.cellIncrementY = -file.cellIncrementY;
179
                        if(minX < file.originX)
180
                                minX = file.originX;
181
                        if(maxY > file.originY)
182
                                maxY = file.originY;
183
                        if(maxX > (file.originX + ((double) (file.width - 1) * file.cellIncrementX)))
184
                                maxX = file.originX + ((double) (file.width - 1) * file.cellIncrementX);
185
                        if(minY < file.originY + ((double) (file.height - 1) * file.cellIncrementY))
186
                                minY = file.originY + ((double) (file.height - 1) * file.cellIncrementY);
187

188
                Extent transformView = new Extent(        minX, minY, maxX, maxY );*/
189
                                v = new Extent(e);
190
                }
191

    
192
                public Extent getView() {
193
                                return v;
194
                }
195

    
196
                private void setFileView(int numBands, int [] bandList, ChunkFrame f)
197
                        throws JNCSFileNotOpenException, JNCSInvalidSetViewException {
198
                                file.setView(file.numBands, bandList, f.v.minX(), f.v.maxY(), f.v.maxX(), f.v.minY(), f.width, f.height);
199
                }
200

    
201
                /**
202
                 * Obtiene un trozo de imagen (determinado por la vista y los par?metros.
203
                 *
204
                 * @param width
205
                 * @param height
206
                 */
207
                public synchronized Image updateImage(int width, int height, ICoordTrans rp) {
208
                                // TODO reproyectar para devolver el trozo de imagen pedida sobre ...
209
                                // la proyecci?n de destino.
210
                                int line = 0;
211
                                Dimension fullSize = null;
212
                                Image ecwImage = null;
213

    
214
                                if (file == null) {
215
                                                return ecwImage;
216
                                }
217

    
218
                                try {
219
                                                int[] bandlist;
220
                                                int[] bandListTriband;
221
                                                int[] pRGBArray = null;
222

    
223
                                                if(mustVerifySize()){
224
                                                // Work out the correct aspect for the setView call.
225
                                                        double dFileAspect = (double) v.width() / (double) v.height();
226
                                                        double dWindowAspect = (double) width / (double) height;
227

    
228
                                                        if (dFileAspect > dWindowAspect) {
229
                                                                        height = (int) ((double) width / dFileAspect);
230
                                                        } else {
231
                                                                        width = (int) ((double) height * dFileAspect);
232
                                                        }
233
                                                }
234
                                                fullSize = new Dimension(width, height);
235

    
236
                                                //System.out.println("fullSize = ("+width+","+height+")");
237
                                                // Peta en los peque?os ... arreglar antes de meter del todo
238
                                                ChunkFrame[] frames = ChunkFrame.computeFrames(file, v, fullSize, extent);
239

    
240
                                                if (frames.length == 1) {
241
                                                                width = frames[0].width;
242
                                                                height = frames[0].height;
243

    
244
                                                                if (width <= 0) {
245
                                                                                width = 1;
246
                                                                }
247

    
248
                                                                if (height <= 0) {
249
                                                                                height = 1;
250
                                                                }
251
                                                }
252

    
253
                                                /*                        JNCSDatasetPoint ptMin = file.convertWorldToDataset(v.minX(), v.minY());
254
                                                                                                                                                JNCSDatasetPoint ptMax = file.convertWorldToDataset(v.maxX(), v.maxY());
255
                                                                                                                                                System.out.println("Dataset coords Width = "+(ptMax.x-ptMin.x)+", px width ="+width);
256
                                                                                                                                                // BEGIN Cambiando para soportar e < 1:1
257
                                                                                                                                                // TODO Mejorarlo para que los PAN con un zoom muy grande sean correctos
258
                                                                                                                                                if ((ptMax.x-ptMin.x)<width) {
259
                                                                                                                                                                                width = ptMax.x-ptMin.x;
260
                                                                                                                                                                                height = ptMin.y-ptMax.y;
261
                                                                                                                                                                                System.out.println("Size=("+width+","+height+")");
262
                                                                                                                                                                                mustResize = true;
263
                                                                                                                                                }*/
264

    
265
                                                // Create an image of the ecw file.
266
                                                if (doTransparency) {
267
                                                                ecwImage = new BufferedImage(width, height,
268
                                                                                                                                                                                 BufferedImage.TYPE_INT_ARGB);
269
                                                } else {
270
                                                                ecwImage = new BufferedImage(width, height,
271
                                                                                                                                                                                 BufferedImage.TYPE_INT_RGB);
272
                                                }
273

    
274
                                                pRGBArray = new int[width];
275

    
276
                                                // Setup the view parameters for the ecw file.
277
                                                bandlist = new int[bandCount];
278
                                                bandListTriband = new int[bandCount];
279

    
280
                                                if (bandCount > 2) {
281
                                                                bandlist[0] = getBand(RED_BAND);
282
                                                                bandlist[1] = getBand(GREEN_BAND);
283
                                                                bandlist[2] = getBand(BLUE_BAND);
284

    
285
                                                                if (bandCount > 3) {
286
                                                                                for (int i = 3; i < bandCount; i++) {
287
                                                                                                bandlist[i] = 0;
288
                                                                                }
289
                                                                }
290
                                                } else {
291
                                                                for (int i = 0; i < bandCount; i++) {
292
                                                                                bandlist[i] = i;
293
                                                                }
294
                                                }
295

    
296
                                                if (bandCount == 3) {
297
                                                                bandListTriband[0] = 0;
298
                                                                bandListTriband[1] = 1;
299
                                                                bandListTriband[2] = 2;
300
                                                }
301

    
302
                                                for (int nChunk = 0; nChunk < frames.length; nChunk++) {
303
                                                                ChunkFrame f = frames[nChunk];
304

    
305
                                                                // Set the view
306
                                                                if (bandCount != 3) {
307
                                                                                setFileView(file.numBands, bandlist, f);
308
                                                                } else {
309
                                                                                setFileView(file.numBands, bandListTriband, f);
310
                                                                }
311

    
312
                                                                /*
313
                                                                 * Esta peli es porque el Ecw no intercambia las bandas con lo que me toca hacerlo
314
                                                                 * a mano. Primero detectamos si se ha alterado el orden de las mismas. Si es as?
315
                                                                 * calculamos mascaras y desplazamientos y hacemos una copia en pRGBArrayCopy
316
                                                                 * con las bandas alteradas de orden
317
                                                                 */
318
                                                                int[] pRGBArrayCopy = null;
319
                                                                int[] mascara = new int[3];
320
                                                                int[] shl = new int[3];
321
                                                                int[] shr = new int[3];
322
                                                                boolean order = true;
323

    
324
                                                                if (bandCount == 3) {
325
                                                                                for (int i = 0; i < bandCount; i++)
326
                                                                                                if (bandlist[i] != i) {
327
                                                                                                                order = false;
328
                                                                                                }
329

    
330
                                                                                if (!order) {
331
                                                                                                for (int i = 0; i < bandCount; i++) {
332
                                                                                                                switch (bandlist[i]) {
333
                                                                                                                case 0:
334
                                                                                                                                mascara[i] = 0x00ff0000;
335
                                                                                                                                break;
336
                                                                                                                case 1:
337
                                                                                                                                mascara[i] = 0x0000ff00;
338
                                                                                                                                break;
339
                                                                                                                case 2:
340
                                                                                                                                mascara[i] = 0x000000ff;
341
                                                                                                                                break;
342
                                                                                                                }
343
                                                                                                                if ((i == 1) && (bandlist[i] == 0))
344
                                                                                                                                shr[i] = 8;
345
                                                                                                                if ((i == 2) && (bandlist[i] == 0))
346
                                                                                                                                shr[i] = 16;
347
                                                                                                                if ((i == 0) && (bandlist[i] == 1))
348
                                                                                                                                shl[i] = 8;
349
                                                                                                                if ((i == 2) && (bandlist[i] == 1))
350
                                                                                                                                shr[i] = 8;
351
                                                                                                                if ((i == 0) && (bandlist[i] == 2))
352
                                                                                                                                shl[i] = 16;
353
                                                                                                                if ((i == 1) && (bandlist[i] == 2))
354
                                                                                                                                shl[i] = 8;
355
                                                                                                }
356
                                                                                }
357
                                                                }
358

    
359
                                                                // Read the scan lines
360
                                                                for (line = 0; line < f.height; line++) {
361
                                                                                file.readLineRGBA(pRGBArray);
362

    
363
                                                                                if ((bandCount == 3) && !order) {
364
                                                                                                pRGBArrayCopy = new int[pRGBArray.length];
365

    
366
                                                                                                for (int i = 0; i < pRGBArray.length; i++) {
367
                                                                                                                pRGBArrayCopy[i] = (pRGBArray[i] & 0xff000000) +
368
                                                                                                                                                                                         (((pRGBArray[i] & mascara[2]) << shl[2]) >> shr[2]) +
369
                                                                                                                                                                                         (((pRGBArray[i] & mascara[1]) << shl[1]) >> shr[1]) +
370
                                                                                                                                                                                         (((pRGBArray[i] & mascara[0]) << shl[0]) >> shr[0]);
371
                                                                                                }
372

    
373
                                                                                                pRGBArray = pRGBArrayCopy;
374
                                                                                }
375

    
376
                                                                                // Prueba de sustituci?n de color transparente
377
                                                                                if (doTransparency) {
378
                                                                                                if (line == 0) {
379
                                                                                                                tFilter.debug = true;
380
                                                                                                }
381

    
382
                                                                                                tFilter.filterLine(pRGBArray);
383
                                                                                                tFilter.debug = false;
384
                                                                                }
385

    
386
                                                                                ((BufferedImage) ecwImage).setRGB(f.pos.x, f.pos.y + line,
387
                                                                                                                                                                                                                        f.width, 1, pRGBArray, 0,
388
                                                                                                                                                                                                                        f.width);
389
                                                                }
390
                                                }
391

    
392
                                                if (frames[0].mustResize) {
393
                                                                //System.out.println("resize "+fullSize);
394
                                                                return resizeImage(fullSize, ecwImage);
395
                                                }
396

    
397
                                                /*
398
                                                 * La excepci?n atrapada es la de 'zoom > 1:1 no valido'
399
                                                } catch (com.ermapper.ecw.JNCSInvalidSetViewException e) {
400
                                                                                System.err.println(errorMessage);
401
                                                                                e.printStackTrace(); */
402
                                } catch (com.ermapper.ecw.JNCSException e) { //java.lang.ArrayIndexOutOfBoundsException:
403
                                                System.err.println("EcwFile JNCS Error en la l?nea " + line + "/" +
404
                                                                                                                         height);
405
                                                System.err.println(e.getMessage());
406
                                                e.printStackTrace();
407
                                } catch (java.lang.ArrayIndexOutOfBoundsException e) { //:
408
                                                System.err.println("EcwFile ArrayIndex Error en la l?nea " + line +
409
                                                                                                                         "/" + height);
410
                                                System.err.println(e.getMessage());
411
                                                e.printStackTrace();
412
                                } catch (Exception e) {
413
                                                errorMessage = e.getMessage();
414

    
415
                                                //                        g.drawString(errorMessage, 0, 50);
416
                                                System.err.println(errorMessage);
417
                                                e.printStackTrace();
418
                                }
419

    
420
                                lastRefreshPercent = file.getPercentComplete();
421
                                System.out.println("Leido al " + lastRefreshPercent + " %.");
422

    
423
                                return ecwImage;
424
                }
425

    
426
                /**
427
                 * Redimensionado de imagen
428
                 * La funci?n getScaledInstance nos devuelve un tipo image que no sirve por lo que
429
                 * habr? que crear  buffImg como BufferedImage y copiar los datos devueltos por esta
430
                 * funci?n a este que es el que ser? devuelto por la funci?n
431
                 * @param sz
432
                 * @param image        Image de entrada
433
                 * @return        Imagen reescalada
434
                 */
435
                private Image resizeImage(Dimension sz, Image image) {
436
                                Image buffImg = null;
437
                                Image img = image.getScaledInstance((int) sz.getWidth(),
438
                                                                                                                                                                                (int) sz.getHeight(),
439
                                                                                                                                                                                Image.SCALE_SMOOTH);
440

    
441
                                //Todo este pollo es para copiar el tipo image devuelto a BufferedImage
442
                                buffImg = new BufferedImage(img.getWidth(null), img.getHeight(null),
443
                                                                                                                                                BufferedImage.TYPE_INT_ARGB);
444

    
445
                                int[] pixels = new int[img.getWidth(null) * img.getHeight(null)];
446
                                PixelGrabber pg = new PixelGrabber(img, 0, 0, img.getWidth(null),
447
                                                                                                                                                                         img.getHeight(null), pixels, 0,
448
                                                                                                                                                                         img.getWidth(null));
449

    
450
                                try {
451
                                                pg.grabPixels();
452
                                } catch (InterruptedException e) {
453
                                                e.printStackTrace();
454
                                }
455

    
456
                                for (int j = 0; j < buffImg.getHeight(null); j++) {
457
                                                for (int i = 0; i < buffImg.getWidth(null); i++) {
458
                                                                ((BufferedImage) buffImg).setRGB(i, j,
459
                                                                                                                                                                                                 pixels[(j * buffImg.getWidth(null)) +
460
                                                                                                                                                                                                 i]);
461
                                                }
462
                                }
463

    
464
                                return buffImg;
465
                }
466

    
467
                /**
468
                 * Reproyecta el raster.
469
                 */
470
                public void reProject(ICoordTrans rp) {
471
                                // TODO metodo reProject pendiente de implementar
472
                }
473

    
474
                /**
475
                 * Soporte para actualizaci?n de la imagen
476
                 * @see com.ermapper.ecw.JNCSProgressiveUpdate#refreshUpdate(int, int, double, double, double, double)
477
                 */
478
                public void refreshUpdate(int nWidth, int nHeight, double dWorldTLX,
479
                                                                                                                        double dWorldTLY, double dWorldBRX,
480
                                                                                                                        double dWorldBRY) {
481
                                int completado = file.getPercentComplete();
482
                                System.out.println("EcwFile: se actualiza 1: " + completado +
483
                                                                                                         " % completado");
484

    
485
                                if ((updatable != null) && (lastRefreshPercent < 100)) {
486
                                                if (((completado - lastRefreshPercent) > 25) ||
487
                                                                                (completado == 100)) {
488
                                                                lastRefreshPercent = file.getPercentComplete();
489
                                                                updatable.repaint();
490
                                                }
491
                                }
492
                }
493

    
494
                public void refreshUpdate(int nWidth, int nHeight, int dDatasetTLX,
495
                                                                                                                        int dDatasetTLY, int dDatasetBRX, int dDatasetBRY) {
496
                                System.out.println("EcwFile: se actualiza 2");
497
                }
498

    
499
                /**
500
                 *  Esta funci?n es porque el Ecw no intercambia las bandas con lo que me toca hacerlo
501
                 * a mano. Primero detectamos si se ha alterado el orden de las mismas. Si es as?
502
                 * calculamos mascaras y desplazamientos y hacemos una copia en pRGBArrayCopy
503
                 * con las bandas alteradas de orden
504
                 * @param bandList        lista de bandas
505
                 * @param mask mascara
506
                 * @param shl desplazamiento izquierda
507
                 * @param shr desplazamiento derecha
508
                 */
509
                private boolean calcMaskAndShift(int[] bandList, int[] mask, int[] shl,
510
                                                                                                                                                 int[] shr) {
511
                                boolean order = true;
512

    
513
                                if (bandCount == 3) {
514
                                                for (int i = 0; i < bandCount; i++)
515
                                                                if (bandList[i] != i) {
516
                                                                                order = false;
517
                                                                }
518

    
519
                                                if (!order) {
520
                                                                for (int i = 0; i < bandCount; i++) {
521
                                                                                switch (bandList[i]) {
522
                                                                                case 0:
523
                                                                                                mask[i] = 0x00ff0000;
524
                                                                                                break;
525
                                                                                case 1:
526
                                                                                                mask[i] = 0x0000ff00;
527
                                                                                                break;
528
                                                                                case 2:
529
                                                                                                mask[i] = 0x000000ff;
530
                                                                                                break;
531
                                                                                }
532

    
533
                                                                                if ((i == 1) && (bandList[i] == 0))
534
                                                                                                shr[i] = 8;
535
                                                                                if ((i == 2) && (bandList[i] == 0))
536
                                                                                                shr[i] = 16;
537
                                                                                if ((i == 0) && (bandList[i] == 1))
538
                                                                                                shl[i] = 8;
539
                                                                                if ((i == 2) && (bandList[i] == 1))
540
                                                                                                shr[i] = 8;
541
                                                                                if ((i == 0) && (bandList[i] == 2))
542
                                                                                                shl[i] = 16;
543
                                                                                if ((i == 1) && (bandList[i] == 2))
544
                                                                                                shl[i] = 8;
545
                                                                }
546
                                                }
547
                                }
548

    
549
                                return order;
550
                }
551

    
552
                /**
553
                 * Intercambio de bandas para ecw manual. Se le pasa el array de bytes que se desea intercambiar
554
                 * la mascara y desplazamientos previamente calculados con calcMaskAndShift
555
                 * @param order        true si el orden de las bandas no est? alterado y false si lo est?
556
                 * @param pRGBArray array de
557
                 * @param mascara
558
                 * @param shl desplazamiento a izquierda
559
                 * @param shr desplazamiento a derecha
560
                 * @return array con las bandas cambiadas
561
                 */
562
                private int[] changeBands(boolean order, int[] pRGBArray, int[] mascara,
563
                                                                                                                        int[] shl, int[] shr) {
564
                                if ((bandCount == 3) && !order) {
565
                                                int[] pRGBArrayCopy = new int[pRGBArray.length];
566

    
567
                                                for (int i = 0; i < pRGBArray.length; i++) {
568
                                                                pRGBArrayCopy[i] = (pRGBArray[i] & 0xff000000) +
569
                                                                                                                                         (((pRGBArray[i] & mascara[2]) << shl[2]) >> shr[2]) +
570
                                                                                                                                         (((pRGBArray[i] & mascara[1]) << shl[1]) >> shr[1]) +
571
                                                                                                                                         (((pRGBArray[i] & mascara[0]) << shl[0]) >> shr[0]);
572
                                                }
573

    
574
                                                return pRGBArrayCopy;
575
                                }
576

    
577
                                return pRGBArray;
578
                }
579

    
580
                /**
581
                 * Asigna al objeto Image los valores con los dato de la imagen contenidos en el
582
                 * vector de enteros.
583
                 * @param image        imagen con los datos actuales
584
                 * @param startX        inicio de la posici?n en X dentro de la imagen
585
                 * @param startY        inicio de la posici?n en X dentro de la imagen
586
                 * @param w        Ancho de la imagen
587
                 * @param h        Alto de la imagen
588
                 * @param rgbArray        vector que contiene la banda que se va a sustituir
589
                 * @param offset        desplazamiento
590
                 * @param scansize        tama?o de imagen recorrida por cada p
591
                 */
592
                protected void setRGBLine(BufferedImage image, int startX, int startY,
593
                                                                                                                        int w, int h, int[] rgbArray, int offset,
594
                                                                                                                        int scansize) {
595
                                image.setRGB(startX, startY, w, h, rgbArray, offset, scansize);
596
                }
597

    
598
                /**
599
                 * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores
600
                 * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
601
                 * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
602
                 * banda correspondiente a flags es sustituida por los datos del vector.
603
                 * @param image        imagen con los datos actuales
604
                 * @param startX        inicio de la posici?n en X dentro de la imagen
605
                 * @param startY        inicio de la posici?n en X dentro de la imagen
606
                 * @param w        Ancho de la imagen
607
                 * @param h        Alto de la imagen
608
                 * @param rgbArray        vector que contiene la banda que se va a sustituir
609
                 * @param offset        desplazamiento
610
                 * @param scansize        tama?o de imagen recorrida por cada paso
611
                 * @param flags        banda que se va a sustituir (Ctes de GeoRasterFile)
612
                 */
613
                protected void setRGBLine(BufferedImage image, int startX, int startY,
614
                                                                                                                        int w, int h, int[] rgbArray, int offset,
615
                                                                                                                        int scansize, int flags) {
616
                                int[] line = new int[rgbArray.length];
617
                                image.getRGB(startX, startY, w, h, line, offset, scansize);
618

    
619
                                if (flags == GeoRasterFile.RED_BAND) {
620
                                                for (int i = 0; i < line.length; i++)
621
                                                                line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000);
622
                                } else if (flags == GeoRasterFile.GREEN_BAND) {
623
                                                for (int i = 0; i < line.length; i++)
624
                                                                line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00);
625
                                } else if (flags == GeoRasterFile.BLUE_BAND) {
626
                                                for (int i = 0; i < line.length; i++)
627
                                                                line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff);
628
                                }
629

    
630
                                image.setRGB(startX, startY, w, h, line, offset, scansize);
631
                }
632

    
633
                /**
634
                 * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores
635
                 * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
636
                 * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
637
                 * banda correspondiente a flags es sustituida por los datos del vector.
638
                 * @param image        imagen con los datos actuales
639
                 * @param startX        inicio de la posici?n en X dentro de la imagen
640
                 * @param startY        inicio de la posici?n en X dentro de la imagen
641
                 * @param w        Ancho de la imagen
642
                 * @param h        Alto de la imagen
643
                 * @param rgbArray        vector que contiene la banda que se va a sustituir
644
                 * @param offset        desplazamiento
645
                 * @param scansize        tama?o de imagen recorrida por cada paso
646
                 * @param origBand        Banda origen del GeoRasterFile
647
                 * @param destBandFlag        banda que se va a sustituir (Ctes de GeoRasterFile)
648
                 */
649
                protected void setRGBLine(BufferedImage image, int startX, int startY,
650
                                                                                                                        int w, int h, int[] rgbArray, int offset,
651
                                                                                                                        int scansize, int origBand, int destBandFlag) {
652
                                int[] line = new int[rgbArray.length];
653
                                image.getRGB(startX, startY, w, h, line, offset, scansize);
654

    
655
                                if ((origBand == 0) && (destBandFlag == GeoRasterFile.RED_BAND)) {
656
                                                for (int i = 0; i < line.length; i++)
657
                                                                line[i] = (line[i] & 0xff00ffff) | (rgbArray[i] & 0x00ff0000);
658
                                } else if ((origBand == 1) &&
659
                                                                                         (destBandFlag == GeoRasterFile.GREEN_BAND)) {
660
                                                for (int i = 0; i < line.length; i++)
661
                                                                line[i] = (line[i] & 0xffff00ff) | (rgbArray[i] & 0x0000ff00);
662
                                } else if ((origBand == 2) &&
663
                                                                                         (destBandFlag == GeoRasterFile.BLUE_BAND)) {
664
                                                for (int i = 0; i < line.length; i++)
665
                                                                line[i] = (line[i] & 0xffffff00) | (rgbArray[i] & 0x000000ff);
666
                                }
667
                                else if ((origBand == 0) && (destBandFlag == GeoRasterFile.GREEN_BAND)) {
668
                                                for (int i = 0; i < line.length; i++)
669
                                                                line[i] = (line[i] & 0xffff00ff) |
670
                                                                                                        ((rgbArray[i] & 0x00ff0000) >> 8);
671
                                } else if ((origBand == 0) &&
672
                                                                                         (destBandFlag == GeoRasterFile.BLUE_BAND)) {
673
                                                for (int i = 0; i < line.length; i++)
674
                                                                line[i] = (line[i] & 0xffffff00) |
675
                                                                                                        ((rgbArray[i] & 0x00ff0000) >> 16);
676
                                }
677
                                else if ((origBand == 1) && (destBandFlag == GeoRasterFile.RED_BAND)) {
678
                                                for (int i = 0; i < line.length; i++)
679
                                                                line[i] = (line[i] & 0xff00ffff) |
680
                                                                                                        ((rgbArray[i] & 0x0000ff00) << 8);
681
                                } else if ((origBand == 1) &&
682
                                                                                         (destBandFlag == GeoRasterFile.BLUE_BAND)) {
683
                                                for (int i = 0; i < line.length; i++)
684
                                                                line[i] = (line[i] & 0xffffff00) |
685
                                                                                                        ((rgbArray[i] & 0x0000ff00) >> 8);
686
                                }
687
                                else if ((origBand == 2) && (destBandFlag == GeoRasterFile.RED_BAND)) {
688
                                                for (int i = 0; i < line.length; i++)
689
                                                                line[i] = (line[i] & 0xff00ffff) |
690
                                                                                                        ((rgbArray[i] & 0x000000ff) << 16);
691
                                } else if ((origBand == 2) &&
692
                                                                                         (destBandFlag == GeoRasterFile.GREEN_BAND)) {
693
                                                for (int i = 0; i < line.length; i++)
694
                                                                line[i] = (line[i] & 0xffff00ff) |
695
                                                                                                        ((rgbArray[i] & 0x000000ff) << 8);
696
                                }
697

    
698
                                image.setRGB(startX, startY, w, h, line, offset, scansize);
699
                }
700

    
701

    
702
                /* (non-Javadoc)
703
                 * @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans, java.awt.Image, int origBand, int destBand)
704
                 */
705
                public Image updateImage(int width, int height, ICoordTrans rp, Image img,
706
                                                                                                                 int origBand, int destBandFlag) throws SupersamplingNotSupportedException{
707
                                //TODO reproyectar para devolver el trozo de imagen pedida sobre ...
708
                                // la proyecci?n de destino.
709
                                int line = 0;
710
                                Dimension fullSize = null;
711
                                boolean trySupersampling = false;
712

    
713
                                if (file == null) {
714
                                                return null;
715
                                }
716

    
717
                                try {
718
                                                int[] bandlist;
719
                                                int[] bandListTriband;
720
                                                int[] pRGBArray = null;
721

    
722
                                                if(mustVerifySize()){
723
                                                        // Work out the correct aspect for the setView call.
724
                                                        double dFileAspect = (double) v.width() / (double) v.height();
725
                                                        double dWindowAspect = (double) width / (double) height;
726

    
727
                                                        if (dFileAspect > dWindowAspect) {
728
                                                                        height = (int) ((double) width / dFileAspect);
729
                                                        } else {
730
                                                                        width = (int) ((double) height * dFileAspect);
731
                                                        }
732
                                                }
733

    
734
                                                fullSize = new Dimension(width, height);
735

    
736
                                                ChunkFrame[] frames = ChunkFrame.computeFrames(file, v, fullSize, extent);
737

    
738
                                                if (frames.length == 1) {
739
                                                                width = frames[0].width;
740
                                                                height = frames[0].height;
741

    
742
                                                                if (width <= 0)
743
                                                                                width = 1;
744

    
745
                                                                if (height <= 0)
746
                                                                                height = 1;
747
                                                }
748

    
749
                                                // Create an image of the ecw file.
750
                                                pRGBArray = new int[width];
751

    
752
                                                // Setup the view parameters for the ecw file.
753
                                                bandlist = new int[bandCount];
754
                                                bandListTriband = new int[bandCount];
755

    
756
                                                if (bandCount > 2) {
757
                                                                bandlist[0] = getBand(RED_BAND);
758
                                                                bandlist[1] = getBand(GREEN_BAND);
759
                                                                bandlist[2] = getBand(BLUE_BAND);
760

    
761
                                                                if (bandCount > 3) {
762
                                                                                for (int i = 3; i < bandCount; i++) {
763
                                                                                                bandlist[i] = 0;
764
                                                                                }
765
                                                                }
766
                                                } else {
767
                                                                for (int i = 0; i < bandCount; i++)
768
                                                                                bandlist[i] = i;
769
                                                }
770

    
771
                                                if (bandCount == 3) {
772
                                                                bandListTriband[0] = 0;
773
                                                                bandListTriband[1] = 1;
774
                                                                bandListTriband[2] = 2;
775
                                                }
776

    
777
                                                int[] mascara = new int[3];
778
                                                int[] shl = new int[3];
779
                                                int[] shr = new int[3];
780
                                                boolean order = true;
781

    
782
                                                if (img == null) { //Caso en el que se crea un Image
783
                                                                EcwFile.nUpdate = 1;
784

    
785
                                                                Image ecwImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
786

    
787
                                                                for (int nChunk = 0; nChunk < frames.length; nChunk++) {
788
                                                                                ChunkFrame f = frames[nChunk];
789

    
790
                                                                                try{
791
                                                                                        if (bandCount != 3) {
792
                                                                                                        setFileView(file.numBands, bandlist, f);
793
                                                                                        } else {
794
                                                                                                        setFileView(file.numBands, bandListTriband, f);
795
                                                                                        }
796
                                                                                }catch(JNCSInvalidSetViewException exc){
797
                                                                                        trySupersampling = true;
798
                                                                                }
799

    
800
                                                                                order = calcMaskAndShift(bandlist, mascara, shl, shr);
801

    
802
                                                                                for (line = 0; line < f.height; line++) {
803
                                                                                                file.readLineRGBA(pRGBArray);
804
                                                                                                pRGBArray = changeBands(order, pRGBArray, mascara, shl, shr);
805
                                                                                                setRGBLine((BufferedImage) ecwImage, f.pos.x, f.pos.y + line, f.width, 1, pRGBArray, 0, f.width);
806
                                                                                }
807
                                                                } //Chuncks
808

    
809
                                                                applyAlpha(ecwImage);
810

    
811
                                                                if (frames[0].mustResize && !this.multifile)
812
                                                                                return resizeImageII(fullSize, ecwImage);
813

    
814
                                                                lastRefreshPercent = file.getPercentComplete();
815

    
816
                                                                //System.out.println("Leido al "+lastRefreshPercent+" %.");
817
                                                                return ecwImage;
818
                                                } else { //Caso en el que se actualiza una banda del Image
819
                                                                EcwFile.nUpdate++;
820

    
821
                                                                for (int nChunk = 0; nChunk < frames.length; nChunk++) {
822
                                                                                ChunkFrame f = frames[nChunk];
823

    
824
                                                                                if (bandCount != 3) {
825
                                                                                                setFileView(file.numBands, bandlist, f);
826
                                                                                } else {
827
                                                                                                setFileView(file.numBands, bandListTriband, f);
828
                                                                                }
829

    
830
                                                                                order = calcMaskAndShift(bandlist, mascara, shl, shr);
831

    
832
                                                                                for (line = 0; line < f.height; line++) {
833
                                                                                                file.readLineRGBA(pRGBArray);
834
                                                                                                pRGBArray = changeBands(order, pRGBArray, mascara, shl, shr);
835
                                                                                                setRGBLine((BufferedImage) img, f.pos.x, f.pos.y + line, f.width, 1, pRGBArray, 0, f.width, origBand, destBandFlag);
836
                                                                                }
837
                                                                } //Chuncks
838

    
839
                                                                applyAlpha(img);
840

    
841
                                                                if (frames[0].mustResize && (nUpdate == 3) && this.multifile) {
842
                                                                                return resizeImageII(fullSize, img);
843
                                                                }
844

    
845
                                                                lastRefreshPercent = file.getPercentComplete();
846

    
847
                                                                //System.out.println("Leido al "+lastRefreshPercent+" %.");
848
                                                                return img;
849
                                                }
850
                                } catch (com.ermapper.ecw.JNCSException e) { //java.lang.ArrayIndexOutOfBoundsException:
851
                                                System.err.println("EcwFile JNCS Error en la l?nea " + line + "/" +
852
                                                                                                                         height);
853
                                                System.err.println(e.getMessage());
854
                                } catch (java.lang.ArrayIndexOutOfBoundsException e) { //:
855
                                                System.err.println("EcwFile ArrayIndex Error en la l?nea " + line +"/" + height);
856
                                                System.err.println(e.getMessage());
857
                                } catch (Exception e) {
858
                                                errorMessage = e.getMessage();
859
                                                System.err.println(errorMessage);
860
                                                if(trySupersampling)
861
                                                        throw new SupersamplingNotSupportedException();
862
                                }
863

    
864
                                return img;
865
                }
866

    
867
                private Image resizeImageII(Dimension sz, Image image) {
868
                                int w = (int)sz.getWidth();
869
                                int h = (int)sz.getHeight();
870
                        Image buffImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
871

    
872
                                //Desplazamiento para la X y la Y leidas. Estas tienen efecto cuando un pixel no empieza a visualizarse
873
                                //justo en su esquina superior izquierda y tiene que ser cortado en la visualizaci?n.
874

    
875
                                double currentViewX = (((double) file.width)/(Math.abs(extent.getMax().getX() - extent.getMin().getX())))*(v.minX()-file.originX);
876
                double currentViewY = (((double) file.height)/(Math.abs(extent.getMax().getY() - extent.getMin().getY())))*(file.originY - v.minY());
877
                                double offsetX = Math.abs(currentViewX - ((int)currentViewX));
878
                                double offsetY = Math.abs(currentViewY - ((int)currentViewY));
879

    
880
                                int xSrc, ySrc;
881
                                int decr = 2;
882

    
883
                                if(v.minX() == extent.minX() || v.maxX() == extent.maxX() || v.minY() == extent.minY() || v.maxY() == extent.maxY()){
884
                                        decr = 0;
885
                                        offsetX = offsetY = 0;
886
                                }
887

    
888
                                double scaleW = (double)((double)(image.getWidth(null) - decr) / (double)w);
889
                                double scaleH = (double)((double)(image.getHeight(null) - decr) / (double)h);
890
                                for (int y1 = 0; y1 < h; y1++){
891
                                ySrc = (int) ((y1 * scaleH) + offsetY);
892
                                        for (int x1 = 0; x1 < w; x1++){
893
                                                xSrc = (int) ((x1 * scaleW) + offsetX);
894
                                                try {
895
                                                        ((BufferedImage) buffImg).setRGB(x1, y1, ((BufferedImage)image).getRGB(xSrc, ySrc));
896
                                                } catch (java.lang.ArrayIndexOutOfBoundsException e) {
897
                                                }
898
                                        }
899
                                }
900

    
901
                                return buffImg;
902
                }
903

    
904

    
905
                private void applyAlpha(Image im) {
906
                                BufferedImage img = (BufferedImage) im;
907
                                int alpha = (getAlpha() & 0xff) << 24;
908
                                int w = img.getWidth();
909
                                int[] line = new int[w];
910

    
911
                                for (int j = 0; j < img.getHeight(); j++) {
912
                                                img.getRGB(0, j, w, 1, line, 0, w);
913

    
914
                                                for (int i = 0; i < w; i++)
915
                                                                line[i] = (alpha | (line[i] & 0x00ffffff));
916

    
917
                                                img.setRGB(0, j, w, 1, line, 0, w);
918
                                }
919
                }
920

    
921
                /* (non-Javadoc)
922
                 * @see org.cresques.io.GeoRasterFile#getData(int, int)
923
                 */
924
                public Object getData(int x, int y, int band) {
925
                                //file.readLineRGBA();
926
                                return null;
927
                }
928

    
929
                /**
930
                 * Devuelve los datos de una ventana solicitada
931
                 * @param ulX        coordenada X superior izda.
932
                 * @param ulY        coordenada Y superior derecha.
933
                 * @param sizeX        tama?o en X de la ventana.
934
                 * @param sizeY tama?o en Y de la ventana.
935
                 * @param band        Banda solicitada.
936
                 */
937
                public byte[] getWindow(int ulX, int ulY, int sizeX, int sizeY, int band) {
938
                                //TODO Nacho: Implementar getWindow de EcwFile
939
                                return null;
940
                }
941

    
942
                /**
943
                 * Obtiene la zona (Norte / Sur)
944
                 * @return true si la zona es norte y false si es sur
945
                 */
946
                public boolean getZone() {
947
                                //TODO Nacho: Implementar getZone de EcwFile
948
                                return false;
949
                }
950

    
951
                /**
952
                 *Devuelve el n?mero de zona UTM
953
                 *@return N?mero de zona
954
                 */
955
                public int getUTM() {
956
                                //                TODO Nacho: Implementar getUTM de EcwFile
957
                                return 0;
958
                }
959

    
960
                /**
961
                 * Obtiene el sistema de coordenadas geograficas
962
                 * @return Sistema de coordenadas geogr?ficas
963
                 */
964
                public String getGeogCS() {
965
                                //TODO Nacho: Implementar getGeogCS de EcwFile
966
                                return new String("");
967
                }
968

    
969
                /**
970
                 * Devuelve el tama?o de bloque
971
                 * @return Tama?o de bloque
972
                 */
973
                public int getBlockSize() {
974
                                //TODO Nacho: Implementar getBlockSize de EcwFile
975
                                return 1;
976
                }
977

    
978
                /**
979
         * Calcula la transformaci?n que se produce sobre la vista cuando la imagen tiene un fichero .rmf
980
         * asociado. En Ecw el origen de coordenadas en Y es el valor m?ximo y decrece hasta el m?nimo.
981
         * @param originX Origen de la imagen en la coordenada X
982
         * @param originY Origen de la imagen en la coordenada Y
983
         */
984
                public void setExtentTransform(double originX, double originY, double psX, double psY) {
985

    
986
        }
987

    
988
                /**
989
                 * Trozo de imagen (Chunk) en que se divide la consulta a la librer?a,
990
                 * para esquivar el bug#2.
991
                 *
992
                 * @author luisw
993
                 */
994
                static class ChunkFrame {
995
                                // Ancho m?ximo (~2500 px)
996
                                final static int MAX_WIDTH = 1536;
997

    
998
                                // Alto m?ximo (no hay l?mite)
999
                                final static int MAX_HEIGHT = 1536;
1000
                                Point pos;
1001
                                Extent v;
1002
                                int width;
1003
                                int height;
1004
                                boolean mustResize = false;
1005

    
1006
                                public ChunkFrame(Extent vista, int w, int h) {
1007
                                                v = vista;
1008
                                                width = w;
1009
                                                height = h;
1010
                                }
1011

    
1012
                                /**
1013
                                 * Calcula el array de chunks (trozos).
1014
                                 * @param file        Fichero ecw que hay que trocear.
1015
                                 * @param v Extent total de la vista.
1016
                                 * @param sz        Tama?o total de la vista.
1017
                                 * @return array de ChunkFrames.
1018
                                 * @throws JNCSFileNotOpenException
1019
                                 */
1020
                                public static ChunkFrame[] computeFrames(JNCSFile file, Extent v,
1021
                                                                                                                                                                                                 Dimension sz, Extent extent)
1022
                                                                                                                                                                        throws JNCSFileNotOpenException {
1023
                                                ChunkFrame[] frames = null;
1024
                                                ChunkFrame f = null;
1025

    
1026
                                                // Calcula el n? de chunks (filas y columnas)
1027
                                                int numCol = (sz.width / MAX_WIDTH);
1028

    
1029
                                                // Calcula el n? de chunks (filas y columnas)
1030
                                                int numRow = (sz.height / MAX_HEIGHT);
1031

    
1032
                                                if ((sz.width - (numCol * MAX_WIDTH)) > 0) {
1033
                                                                numCol++;
1034
                                                }
1035

    
1036
                                                if ((sz.height - (numRow * MAX_HEIGHT)) > 0) {
1037
                                                                numRow++;
1038
                                                }
1039

    
1040
                                                frames = new ChunkFrame[numCol * numRow];
1041

    
1042
                                                JNCSDatasetPoint ptMin = file.convertWorldToDataset(v.minX(), v.minY());
1043
                                                JNCSDatasetPoint ptMax = file.convertWorldToDataset(v.maxX(), v.maxY());
1044

    
1045
                                                //No utilizamos JNCSDatasetPoint porque siempre hace un redondeo por abajo con lo que perdemos precisi?n. En su lugar
1046
                                                //utilizamos currentViewM... calculado manualmente y que nos proporciona todos los decimales
1047
                                                double currentViewMinX = (((double) file.width)/(Math.abs(extent.getMax().getX() - extent.getMin().getX())))*(v.minX()-file.originX);
1048
                                                double currentViewMaxX = (((double) file.width)/(Math.abs(extent.getMax().getX() - extent.getMin().getX())))*(v.maxX()-file.originX);
1049
                                double currentViewMinY = (((double) file.height)/(Math.abs(extent.getMax().getY() - extent.getMin().getY())))*(file.originY - v.minY());
1050
                                double currentViewMaxY = (((double) file.height)/(Math.abs(extent.getMax().getY() - extent.getMin().getY())))*(file.originY - v.maxY());
1051

    
1052
                                                if ((ptMax.x - ptMin.x) < sz.width) {
1053
                                                                numCol = numRow = 1;
1054
                                                                frames = new ChunkFrame[numCol * numRow];
1055
                                                                int nPixelsX = (int)Math.ceil(Math.abs(currentViewMaxX - currentViewMinX));
1056
                                                                int nPixelsY = (int)Math.ceil(Math.abs(currentViewMaxY - currentViewMinY));
1057

    
1058
                                                                if(v.minX() == extent.minX() || v.maxX() == extent.maxX() || v.minY() == extent.minY() || v.maxY() == extent.maxY()){
1059
                                                                        f = frames[0] = new ChunkFrame(v, nPixelsX, nPixelsY);
1060
                                                                        f.v = new Extent(v);
1061
                                                                }else{
1062
                                                                        f = frames[0] = new ChunkFrame(v, nPixelsX + 1, nPixelsY + 1);
1063
                                                                        double pointEndWcX = v.minX() + (((nPixelsX + 1) * Math.abs(v.maxX() - v.minX())) / nPixelsX);
1064
                                                                        double pointEndWcY = v.maxY() - (((nPixelsY + 1) * Math.abs(v.maxY() - v.minY())) / nPixelsY);
1065
                                                                        f.v = new Extent(v.minX(), v.maxY(), pointEndWcX, pointEndWcY);
1066
                                                                }
1067

    
1068
                                                                f.pos = new Point(0, 0);
1069
                                                                f.mustResize = true;
1070
                                                } else {
1071
                                                                // Calcula cada chunk
1072
                                                                double stepx = ((double) ptMax.x - ptMin.x) / sz.getWidth();
1073
                                                                double stepy = ((double) ptMax.y - ptMin.y) / sz.getHeight();
1074
                                                                int h = sz.height;
1075

    
1076
                                                                for (int r = 0; r < numRow; r++) {
1077
                                                                                int w = sz.width;
1078

    
1079
                                                                                for (int c = 0; c < numCol; c++) {
1080
                                                                                                f = new ChunkFrame(null, -1, -1);
1081

    
1082
                                                                                                // Posici?n del chunk
1083
                                                                                                f.pos = new Point(c * MAX_WIDTH, r * MAX_HEIGHT);
1084

    
1085
                                                                                                // Tama?o del chunk
1086
                                                                                                f.width = Math.min(MAX_WIDTH, w);
1087
                                                                                                f.height = Math.min(MAX_HEIGHT, h);
1088

    
1089
                                                                                                // Extent del chunk
1090
                                                                                                int x1 = ptMin.x + (int) (f.pos.x * stepx);
1091
                                                                                                int x2 = x1 + (int) (f.width * stepx);
1092
                                                                                                int y1 = ptMax.y - (int) (f.pos.y * stepy);
1093
                                                                                                int y2 = y1 - (int) (f.height * stepy); //ptMin.y;
1094
                                                                                                JNCSWorldPoint pt1 = file.convertDatasetToWorld(x1, y1);
1095
                                                                                                JNCSWorldPoint pt2 = file.convertDatasetToWorld(x2, y2);
1096

    
1097
                                                                                                f.v = new Extent(pt1.x, pt1.y, pt2.x, pt2.y); // Hay que calcularlo
1098
                                                                                                frames[(r * numCol) + c] = f;
1099
                                                                                                w -= MAX_WIDTH;
1100
                                                                                }
1101

    
1102
                                                                                h -= MAX_HEIGHT;
1103
                                                                }
1104
                                                }
1105

    
1106
                                                //System.out.println("Hay "+numRow+" filas y "+numCol+" columnas.");
1107
                                                return frames;
1108
                                }
1109
                }
1110
}