11package edu .caltech .ipac .firefly .server .visualize ;
22
3- import edu .caltech .ipac .firefly .data .HasSizeOf ;
43import edu .caltech .ipac .firefly .visualize .Band ;
54import edu .caltech .ipac .firefly .visualize .PlotState ;
65import edu .caltech .ipac .visualize .plot .ActiveFitsReadGroup ;
1413import nom .tam .fits .Header ;
1514
1615import java .awt .Color ;
17- import java .io .Serializable ;
1816import java .util .ArrayList ;
17+ import java .util .HashMap ;
1918import java .util .List ;
2019import java .util .concurrent .Callable ;
2120import java .util .concurrent .ExecutorService ;
3231 */
3332public class DirectStretchUtils {
3433
35- public enum CompressType {FULL , HALF , HALF_FULL , QUARTER_HALF , QUARTER_HALF_FULL }
34+ public enum CompressType {FULL , HALF , QUARTER , HALF_FULL , QUARTER_HALF , QUARTER_HALF_FULL }
3635
3736
3837 private static ExecutorService makeExecutorService () {
@@ -60,7 +59,7 @@ public static StretchDataInfo getStretchDataMask(PlotState state, ActiveFitsRead
6059 var sTileList = doTileStretch (sv ,tileSize , StretchMaskTile ::new ,
6160 (stdef , strContainer ) -> () -> strContainer .stretch (stdef , maskList , flip1d ,fr .getNaxis1 ()) );
6261
63- byte [] byte1d = combineArray ( flip1d . length , sTileList .stream ().map ( st -> st .result ).toList () );
62+ List < byte []> byte1d = sTileList .stream ().map ( st -> st .result ).toList ();
6463 return new StretchDataInfo (byte1d , null , null , getRangeValuesToUse (state ));
6564 }
6665
@@ -81,41 +80,36 @@ private static StretchDataInfo getStretch3C(PlotState state, ActiveFitsReadGroup
8180 FitsRead fr = frGroup .getFitsRead (state .firstBand ());
8281 StretchVars sv = getStretchVars (fr ,tileSize , ct );
8382 RangeValues [] rvAry = getRangeValuesToUse (state );
84- int bPos = 0 ;
85- int bPosHalf =0 ;
86- int bPosQuarter =0 ;
8783 Band [] bands = state .getBands ();
8884 ThreeCComponents tComp = get3CComponents (frGroup ,sv .totWidth ,sv .totHeight ,state );
8985 RGBIntensity rgbI = get3CRGBIntensity (state ,frGroup ,bands );
9086 new ArrayList <Stretch3CTile >(sv .tileLen );
9187
92- var sTileList =doTileStretch (sv ,tileSize , Stretch3CTile ::new ,
88+ List < Stretch3CTile > sTileList =doTileStretch (sv ,tileSize , Stretch3CTile ::new ,
9389 (stdef ,strContainer ) -> () -> strContainer .stretch (stdef , rvAry , tComp .float1dAry ,tComp .imHeadAry ,tComp .histAry ,rgbI ) );
94- int bLen = state . getBands (). length ;
95- byte [] byte1d = new byte [ sv . totWidth * sv . totHeight * bLen ] ;
96- byte [] byte1dHalf = useHalf (ct ) ? new byte [ dRoundUp ( sv . totWidth , 2 ) * dRoundUp ( sv . totHeight , 2 ) * bLen ] : null ;
97- byte [] byte1dQuarter = useQuarter (ct ) ? new byte [ dRoundUp ( sv . totWidth , 4 ) * dRoundUp ( sv . totHeight , 4 ) * bLen ] : null ;
90+
91+ var byte1d = useFull ( ct ) ? new HashMap < Band , List < byte []>>() : null ;
92+ var byte1dHalf = useHalf (ct ) ? new HashMap < Band , List < byte []>>() : null ;
93+ var byte1dQuarter =useQuarter (ct ) ? new HashMap < Band , List < byte []>>() : null ;
9894
9995 for (Stretch3CTile stretchTile : sTileList ) {
100- byte [][] tmpByte3CAry = stretchTile .result ;
101- for (int bandIdx =0 ; (bandIdx <3 );bandIdx ++) {
102- if (tComp .float1dAry [bandIdx ]!=null ) {
103- System .arraycopy (tmpByte3CAry [bandIdx ],0 ,byte1d ,bPos ,tmpByte3CAry [bandIdx ].length );
104- bPos +=tmpByte3CAry [bandIdx ].length ;
105- if (useHalf (ct )) {
106- byte [] hDecimatedAry = stretchTile .resultHalf [bandIdx ];
107- System .arraycopy (hDecimatedAry , 0 , byte1dHalf , bPosHalf , hDecimatedAry .length );
108- bPosHalf += hDecimatedAry .length ;
109- }
110- if (useQuarter (ct )) {
111- byte [] qDecimatedAry = stretchTile .resultQuarter [bandIdx ];
112- System .arraycopy (qDecimatedAry , 0 , byte1dQuarter , bPosQuarter , qDecimatedAry .length );
113- bPosQuarter += qDecimatedAry .length ;
114- }
96+ for (Band band : bands ) {
97+ if (useFull (ct )) {
98+ byte1d .computeIfAbsent (band , k -> new ArrayList <>())
99+ .add (stretchTile .result [band .getIdx ()]);
100+ }
101+ if (useHalf (ct )) {
102+ byte1dHalf .computeIfAbsent (band , k -> new ArrayList <>())
103+ .add (stretchTile .resultHalf [band .getIdx ()]);
104+ }
105+ if (useQuarter (ct )) {
106+ byte1dQuarter .computeIfAbsent (band , k -> new ArrayList <>())
107+ .add (stretchTile .resultQuarter [band .getIdx ()]);
115108 }
116109 }
117110 }
118- return new StretchDataInfo (byte1d , byte1dHalf , byte1dQuarter , rvAry );
111+
112+ return new StretchDataInfo (byte1d ,byte1dHalf ,byte1dQuarter , rvAry );
119113 }
120114
121115 private static <T > List <T > doTileStretch (StretchVars sv , int tileSize , Callable <T > stretchContainerFactory ,
@@ -137,21 +131,14 @@ private static <T> List<T> doTileStretch(StretchVars sv, int tileSize, Callable<
137131 }
138132
139133 private static StretchDataInfo buildStandardResult (List <StretchStandardTile > sTileList , RangeValues rv ,
140- int totWidth , int totHeight , CompressType ct ) throws Exception {
141- var taskList = new ArrayList <Callable <Void >>();
142- byte [] byte1d = useFull (ct ) ? new byte [totWidth *totHeight ] : null ;
143- byte [] byte1dQuarter = useQuarter (ct ) ? new byte [dRoundUp (totWidth ,4 ) * dRoundUp (totHeight ,4 )]:null ;
144- byte [] byte1dHalf = useHalf (ct ) ? new byte [dRoundUp (totWidth ,2 ) * dRoundUp (totHeight ,2 )]:null ;
145- if (useFull (ct )) {
146- taskList .add (() -> combineArray (byte1d , sTileList .stream ().map ( st -> st .result ).toList ()));
147- }
148- if (useQuarter (ct )) {
149- taskList .add (() -> combineArray (byte1dQuarter , sTileList .stream ().map ( st -> st .resultQuarter ).toList ()));
150- }
151- if (useHalf (ct )) {
152- taskList .add (() -> combineArray (byte1dHalf , sTileList .stream ().map ( st -> st .resultHalf ).toList ()));
153- }
154- invokeList (taskList );
134+ int totWidth , int totHeight , CompressType ct ) throws Exception {
135+ List <byte []> byte1d = useFull (ct ) ?
136+ sTileList .stream ().map ( st -> st .result ).toList () : null ;
137+ List <byte []> byte1dHalf = useHalf (ct ) ?
138+ sTileList .stream ().map ( st -> st .resultHalf ).toList () : null ;
139+ List <byte []> byte1dQuarter = useQuarter (ct ) ?
140+ sTileList .stream ().map ( st -> st .resultQuarter ).toList () : null ;
141+
155142 return new StretchDataInfo (byte1d , byte1dHalf , byte1dQuarter , new RangeValues [] {rv });
156143 }
157144
@@ -179,18 +166,6 @@ private static boolean useFull(CompressType ct) {
179166 return ct ==CompressType .FULL || ct ==CompressType .HALF_FULL || ct ==CompressType .QUARTER_HALF_FULL ;
180167 }
181168
182- private static float [] flipFloatArray (float [] float1d , int naxis1 , int naxis2 ) {
183- float [] flipped = new float [float1d .length ];
184- int idx =0 ;
185- for (int y = naxis2 -1 ; y >=0 ; y --) {
186- for (int x = 0 ; x <naxis1 ; x ++) {
187- flipped [idx ]= float1d [y *naxis1 +x ];
188- idx ++;
189- }
190- }
191- return flipped ;
192- }
193-
194169 private static StretchVars getStretchVars (FitsRead fr , int tileSize , CompressType ct ) {
195170 int totWidth = fr .getNaxis1 ();
196171 int totHeight = fr .getNaxis2 ();
@@ -240,21 +215,6 @@ private static RangeValues[] getRangeValuesToUse(PlotState state) {
240215 return new RangeValues [] { state .getRangeValues (RED ), state .getRangeValues (GREEN ), state .getRangeValues (BLUE ) };
241216 }
242217
243- private static Void combineArray (byte [] target , List <byte []> aList ) {
244- int pos = 0 ;
245- for (var dAry : aList ) {
246- System .arraycopy (dAry , 0 , target , pos , dAry .length );
247- pos += dAry .length ;
248- }
249- return null ;
250- }
251-
252- private static byte [] combineArray (int length , List <byte []> aList ) {
253- byte [] target = new byte [length ];
254- combineArray (target ,aList );
255- return target ;
256- }
257-
258218 private static int dRoundUp (int v , int factor ) { return v % factor == 0 ? v /factor : v /factor +1 ; }
259219
260220 private static byte [] makeDecimated (byte [] in , int factor , int width , int height ) {
@@ -312,70 +272,7 @@ private record ThreeCComponents(float[][] float1dAry, ImageHeader[] imHeadAry, H
312272 private record StretchVars (int totWidth , int totHeight , int xPanels , int yPanels , int tileLen , CompressType ct ) {}
313273 private record StretchTileDef (int x , int y , int width , int height , CompressType ct ) {}
314274
315- public static class StretchDataInfo implements Serializable , HasSizeOf {
316- private final byte [] byte1d ;
317- private final byte [] byte1dHalf ;
318- private final byte [] byte1dQuarter ;
319- private final RangeValues [] rvAry ;
320-
321- public StretchDataInfo (byte [] byte1d , byte [] byte1dHalf , byte [] byte1dQuarter , RangeValues [] rvAry ) {
322- this .byte1d = byte1d ;
323- this .byte1dHalf = byte1dHalf ;
324- this .byte1dQuarter = byte1dQuarter ;
325- this .rvAry = rvAry ;
326- }
327-
328- public byte [] findMostCompressAry (CompressType ct ) {
329- return switch (ct ) {
330- case FULL -> byte1d ;
331- case QUARTER_HALF_FULL , QUARTER_HALF -> byte1dQuarter ;
332- case HALF , HALF_FULL -> byte1dHalf ;
333- };
334- }
335-
336- public static String getMostCompressedDescription (CompressType ct ) {
337- return switch (ct ) {
338- case FULL -> "Full" ;
339- case QUARTER_HALF_FULL , QUARTER_HALF -> "Quarter" ;
340- case HALF , HALF_FULL -> "Half" ;
341- };
342- }
343-
344- public boolean isRangeValuesMatching (PlotState state ) {
345- if (!state .isThreeColor ()) {
346- return rvAry .length ==1 && rvAry [0 ].toString ().equals (state .getRangeValues ().toString ());
347- }
348- for (Band band : new Band []{RED , GREEN , BLUE }) {
349- if (state .isBandUsed (band )) {
350- int idx = band .getIdx ();
351- if (rvAry [idx ]==null || !rvAry [idx ].toString ().equals (state .getRangeValues (band ).toString ())) {
352- return false ;
353- }
354- }
355- }
356- return true ;
357- }
358-
359- /**
360- * create a version of the object with only the full byte array and optionally the half if the
361- * CompressType is only using the quarter
362- * @return a version of StretchDataInfo without all the data we will not use again
363- */
364- public StretchDataInfo copyParts (CompressType ct ) {
365- boolean keepHalf = ct == CompressType .QUARTER_HALF_FULL || ct == CompressType .QUARTER_HALF ;
366- return new StretchDataInfo (byte1d , keepHalf ?byte1dHalf :null , null , rvAry );
367- }
368-
369- @ Override
370- public long getSizeOf () {
371- long sum = rvAry .length * 80L ;
372- if (byte1d !=null ) sum +=byte1d .length ;
373- if (byte1dHalf !=null ) sum +=byte1dHalf .length ;
374- if (byte1dQuarter !=null ) sum +=byte1dQuarter .length ;
375- return sum ;
376- }
377- }
378- private static class Stretch3CTile {
275+ private static class Stretch3CTile {
379276 byte [][] result ;
380277 byte [][] resultHalf ;
381278 byte [][] resultQuarter ;
0 commit comments