/* * Copyright(c) 2018, Space Science and Engineering Center, UW-Madison * Refer to "McIDAS Software Acquisition and Distribution Policies" * in the file mcidas/data/license.txt */ /**** $Id: rgbdisp.c,v 1.31 2019/11/14 21:57:11 davep Exp $ ****/ /* *? RGBDISP -- Displays a color image using three frames or datasets as RGB components *? RGBDISP red green blue frame *? RGBDISP rgb_dataset frame *? Parameters: *? red green blue | red, green and blue inputs, respectively, to use for *? the output color image; specify the values as either *? three image frame numbers or as three ADDE datasets in *? alias.position or group/descriptor.position format; *? see the Remarks (no def for frame numbers or ADDE *? dataset names, def=0 for ADDE dataset position) *? rgb_dataset | single ADDE dataset to use as the red, green and blue inputs *? for the output color image; specify the dataset as *? alias.position or group/descriptor.position (no def for *? alias or group/descriptor, def=0 for position) *? frame | destination frame to display the output color image (def=current *? frame) *? Keywords: *? BANd=red green blue | band number to use for the image(s) specified *? in the red, green and blue datasets (def=existing *? band for single-band images; no def for multiband *? images) *? DAY= | day of the image(s) to select in the red, green and blue datasets *? ECHo=YES | show the IMGDISP commands that are run by RGBDISP (def=NO) *? LATlon=red green blue | latitude and longitude of the image(s) specified *? in the red, green and blue datasets to place at the *? frame location specified in the PLACE= keyword; *? see the Remarks for how to specify the values *? LINele=red green blue sys | line and element of the image(s) specified *? in the red, green and blue datasets to place at the *? frame location specified in the PLACE= keyword; *? sys is the coordinate system of the line and element *? values - either F for file, or I for image coordinates *? (no def for red,green,blue; sys def=F); *? see the Remarks for how to specify the values *? MAG=red green blue | line and element magnifications to use for the *? image(s) specified in the red, green and blue datasets *? and BAND= keyword; specify each of the three values as *? either an unquoted single number or a quoted pair of *? numbers; see the Remarks (default=1 red red) *? PLAce= | location on the frame to place the point(s) specified in the *? LATLON, STATION or LINELE keyword; valid options are ULEFT and *? CENTER for upper-left corner & center of the frame, respectively *? (def=ULEFT when LINELE is used; def=CENTER when LATLON or *? STATION is used) *? STAtion= | station ID to place at the image location specified in *? the PLACE keyword; specify as the ID, e.g., KMSN or YSSY, *? optionally followed by station type in brackets, e.g., *? ARX[N] or ARX[V]; see the TYPE keyword in STNLIST command *? for details *? TIMe=btime etime | time of the image(s) to select in the red, green and *? blue datasets; if a btime etime range is specified *? and multiple images are within the range, the latest *? image is displayed (btime def=none; etime def=btime) *? Remarks: *? The RGBDISP command uses the displayed brightness (BRIT) values of the *? three input frames or datasets to calculate the red, green and blue *? components, respectively, of the output color image that is displayed *? in the 'frame' parameter. RGBDISP works only with single-panel frames, *? so should not be used with multipanel frames. *? *? The BAND=, DAY=, LATLON=, LINELE=, MAG=, PLACE=, STATION= and TIME= *? keywords are used only when specifying ADDE datasets, not frame *? numbers, for the three inputs ('red', 'green' and 'blue' parameters *? or 'rgb_dataset' parameter). *? *? When using the "red green blue frame" command format (with either frame *? numbers or datasets), you can exclude one of the three inputs from the *? analysis so the output color image is created using only two input *? images. To do so, specify a 0 (zero) for the corresponding input *? ('red', 'green' or 'blue' parameter) you want to exclude. For example, *? RGBDISP 0 5 6 10 displays an output color image in frame 10 that was *? created using only the image displayed frame 5 for its green component *? and the image displayed in frame 6 for its blue component. If you are *? also using the BAND=, LATLON=, LINELE= or MAG= keyword(s), specify an *? 'X' as a placeholder in the positional parameter(s) of the input you are *? excluding. For example, RGBDISP GOES16/M1 0 GOES16/M1 21 BAND=11 X 15 *? displays an output color image in frame 21 that was created using only *? the GOES16/M1 band 11 image for its red component and GOES16/M1 band 15 *? for its blue component. *? *? The LATlon= and LINele= keywords specify the latitude/longitude or *? line/element position of the image(s) specified in the red, green and *? blue datasets to place at the frame location specified in the PLACE= *? keyword. To use the same position for all three images, specify a single *? pair of numbers. To use different positions for two or all three images, *? specify three pairs of numbers (six total). In both cases, single quotes *? surrounding the pair(s) of numbers is optional. *? The two examples below both specify lat/lon coordinate 45,80 for all *? three images. *? LATLON=45 80 *? LATLON='45 80' *? The two examples below both specify lat/lon coordinates 30.1,95.1 for *? the first image, 30.0,95.0 for the second, and 29.9,94.9 for the third. *? LATLON=30.1 95.1 30.0 95.0 29.9 94.9 *? LATLON='30.1 95.1' '30.0 95.0' '29.9 94.9' *? The two examples below both specify file coordinates 1000,2000 for all *? three images. *? LINELE=1000 2000 F *? LINELE='1000 2000' F *? The two examples below both specify image coordinates 1000,2000 for the *? first image, 1500,3000 for the second, and 1000,2000 for the third. *? LINELE=1000 2000 1500 3000 1000 2000 I *? LINELE='1000 2000' '1500 3000' '1000 2000' I *? *? The "MAG=red green blue" keyword specifies the line and element *? magnifications to use for the images specified in the red, green and *? blue datasets (or rgb_dataset) and BAND= keyword. Specify each of the *? three values as either an unquoted single number (if the line and element *? magnification values are the same) or a quoted pair of numbers (if they *? are different). If just one or two values are specified, they are used *? for the red input and are also the default for the green and blue inputs. *? You must specify values for all three images or just the first image. *? Examples: *? MAG=2 does a 2x2 blowup of all three images *? MAG=-2 2x2 blowdown of all three images *? MAG=2 3 2x3 blowup of all three images *? MAG='2 3' 2x3 blowup of all three images *? MAG=1 -3 1x3 blowdown of all three images *? MAG=2 4 2 2x2 blowup of 1st, 4x4 blowup of 2nd, 2x2 blowup of 3rd *? MAG=2 '2 3' 2 2x2 blowup of 1st, 2x3 blowup of 2nd, 2x2 blowup of 3rd *? MAG='2 3' 2 '3 2' 2x3 blowup of 1st, 2x2 blowup of 2nd, 3x2 blowup of 3rd *? MAG='2 3' '1 -2' '1 -2' 2x3 blowup of 1st, 1x2 blowdown of 2nd and 3rd *? *? If RGBDISP's output image is not what you expect (e.g., colors are *? missing or incorrect), you may be able to correct it by changing the *? visual mode / Pseudocolor settings in your X server configuration or by *? enabling (uncommenting) the -displayVisualMode flag in the $HOME/.mcidasrc *? file. As noted in the .mcidasrc file, setting the flag may also result *? in a slowdown in commands that write image or graphic output. *? ---------- */ #include #include #include #include #include #include #include "mcidas.h" #include "m0glue.h" int M0getfrm(int frame, Fint *array); int M0putfrm(int frame, const Fint *array); int add_parameters(char *r_key, char *g_key, char *b_key, char params[7][64], int count); void make_imgdisp(char *params, int dest_frame); void strclean(char clean_ptr[], char *val_ptr); char *strtokqt(char *input, char *delimit); int main(int argc, char **argv) { char *cmdline, *cmdtoken; const char *cmdsep; const char r_imgdisp[1024], g_imgdisp[1024], b_imgdisp[1024]; char rgb_label[1024]; char in_keyword[64]; char key_params[7][64]; const char r_keyword[64], g_keyword[64], b_keyword[64]; char *key_ptr, *val_ptr; char clean_ptr[4096]; int tok_idx, rgb_idx; int r_frame, r_lines, r_elems; int g_frame, g_lines, g_elems; int b_frame, b_lines, b_elems; int n_frame; int dest_frame, dest_lines, dest_elems; const char *r_data, *g_data, *b_data; int frame_count; int ds_state, key_state; int do_echo; static Fint frameDirectory[64]; int navBlock[640]; M0frameflags *frame_flags; Fint *s_base, *dest_base; size_t s_size; int linele_ok, ok; /* Shared memory segment vars */ unsigned char *s_data; size_t gb_size; int shm_key; unsigned char *m0gbuc; /* initialize */ shm_key = -1; cmdsep = " "; tok_idx = 0; rgb_idx = 0; ds_state = 0; key_state = 0; r_frame = g_frame = b_frame = n_frame = dest_frame = -1; r_data = g_data = b_data = NULL; linele_ok = 1; do_echo = 0; memset(&r_keyword, 0, sizeof(r_keyword)); memset(&r_imgdisp, 0, sizeof(r_imgdisp)); memset(&g_keyword, 0, sizeof(g_keyword)); memset(&g_imgdisp, 0, sizeof(g_imgdisp)); memset(&b_keyword, 0, sizeof(b_keyword)); memset(&b_imgdisp, 0, sizeof(b_imgdisp)); if (Mcinit(argc, argv) < 0) { fprintf(stderr, "%s\n", Mciniterr()); return 1; } frame_count = Mcluc(UC_NUMBER_OF_FRAMES); dest_frame = 0; /* Parse the commandline, looking for: * Digits indicating source frame, possible destination frame at end * Otherwise tokens indicating source dataset, build IMGDISP commands * Possible destination frame at end */ cmdline = Mccmd(); cmdtoken = strtokqt(cmdline, cmdsep); cmdtoken = strtokqt(NULL, cmdsep); /* No tokens to be had */ if (cmdtoken == NULL) { Mceprintf("Error getting red source\n"); return 1; } /* First token may be 0 to indicate no red source */ if (cmdtoken != NULL && isdigit(*cmdtoken) && atoi(cmdtoken) == 0) { r_frame = 0; strcpy(&r_imgdisp, "0 "); rgb_idx++; tok_idx++; cmdtoken = strtokqt(NULL, cmdsep); /* Second token may be 0 to indicate no green source */ if (cmdtoken != NULL && isdigit(*cmdtoken) && atoi(cmdtoken) == 0) { g_frame = 0; strcpy(&g_imgdisp, "0 "); rgb_idx++; tok_idx++; cmdtoken = strtokqt(NULL, cmdsep); } } /* Check first token to see if we are using frame # or datasets */ if (cmdtoken != NULL && isdigit(*cmdtoken)) { Mcdprintf("Using frame # parsing\n"); if (rgb_idx == 0) { r_frame = atoi(cmdtoken); rgb_idx++; if (r_frame < 0 || r_frame > frame_count) { Mceprintf("Invalid red frame number: %d\n", r_frame); return 1; } cmdtoken = strtokqt(NULL, cmdsep); } if (rgb_idx == 1) { if (cmdtoken != NULL && isdigit(*cmdtoken)) { g_frame = atoi(cmdtoken); rgb_idx++; if (g_frame < 0 || g_frame > frame_count) { Mceprintf("Invalid green frame number: %d\n", g_frame); return 1; } } else { Mceprintf("Error getting green source\n"); return 1; } cmdtoken = strtokqt(NULL, cmdsep); } if (rgb_idx == 2) { if (cmdtoken != NULL && isdigit(*cmdtoken)) { b_frame = atoi(cmdtoken); rgb_idx++; if (b_frame < 0 || b_frame > frame_count) { Mceprintf("Invalid blue frame number: %d\n", b_frame); return 1; } } else { Mceprintf("Error getting blue source\n"); return 1; } } /* See if we have a destination or ECHO keyword, consume rest */ while ((cmdtoken = strtokqt(NULL, cmdsep)) != NULL) { if (isdigit(*cmdtoken)) { dest_frame = atoi(cmdtoken); if (dest_frame < 1 || dest_frame > frame_count) { Mceprintf("Invalid destination frame number: %d\n", dest_frame); return 1; } } else if (!strcmp(cmdtoken, "ECH=Y") || !strcmp(cmdtoken, "ECHO=Y") || !strcmp(cmdtoken, "ECH=YE") || !strcmp(cmdtoken, "ECHO=YE") || !strcmp(cmdtoken, "ECH=YES") || !strcmp(cmdtoken, "ECHO=YES")) { do_echo = 1; } /* Disallowed keywords */ else if (strstr(cmdtoken, "PAN=") != NULL || strstr(cmdtoken, "PANE=") != NULL || strstr(cmdtoken, "PANEL=") != NULL) { Mceprintf("Not compatible with PANEL=\n"); return 1; } else if (strstr(cmdtoken, "ALL=") != NULL) { Mceprintf("Not compatible with ALL=\n"); return 1; } else if (strstr(cmdtoken, "SEQ=") != NULL) { Mceprintf("Not compatible with SEQ=\n"); return 1; } else if (strstr(cmdtoken, "CYC=") != NULL || strstr(cmdtoken, "CYCL=") != NULL || strstr(cmdtoken, "CYCLE=") != NULL) { Mceprintf("Not compatible with CYCLE=\n"); return 1; } else if (strstr(cmdtoken, "REP=") != NULL || strstr(cmdtoken, "REPE=") != NULL || strstr(cmdtoken, "REPEA=") != NULL || strstr(cmdtoken, "REPEAT=") != NULL) { Mceprintf("Not compatible with REPEAT=\n"); return 1; } } } /* Using datasets */ else { Mcdprintf("Using dataset parsing\n"); if (rgb_idx == 0) { strcpy(&r_imgdisp, cmdtoken); strcpy(&g_imgdisp, cmdtoken); strcpy(&b_imgdisp, cmdtoken); } else if (rgb_idx == 1) { strcpy(&g_imgdisp, cmdtoken); } else if (rgb_idx == 2) { strcpy(&b_imgdisp, cmdtoken); } rgb_idx++; tok_idx++; while ((cmdtoken = strtokqt(NULL, cmdsep)) != NULL) { /* Found a dataset token */ if (ds_state == 0 && !isdigit(*cmdtoken) && strchr(cmdtoken, '=') == NULL ) { if (rgb_idx == 1 && tok_idx == 1) { strcpy(&g_imgdisp, cmdtoken); } else if (rgb_idx == 2 && tok_idx == 2) { strcpy(&b_imgdisp, cmdtoken); } else { Mceprintf("Unknown dataset parameter following RGB datasets: %s\n", cmdtoken); return 1; } rgb_idx++; tok_idx++; continue; } /* Destination frame or 0 */ if (key_state == 0 && isdigit(*cmdtoken)) { if (dest_frame > 0) { Mceprintf("Unknown digit parameter following RGB datasets\n"); return 1; } if (atoi(cmdtoken) == 0) { if (rgb_idx == 1) { strcpy(&g_imgdisp, "0 "); rgb_idx++; tok_idx++; continue; } else if (rgb_idx == 2) { strcpy(&b_imgdisp, "0 "); rgb_idx++; tok_idx++; continue; } } dest_frame = atoi(cmdtoken); if (dest_frame < 1 || dest_frame > frame_count) { dest_frame = atoi(cmdtoken); Mceprintf("Invalid destination frame number: %d\n", dest_frame); return 1; } continue; } /* Look for keywords */ if ((strchr(cmdtoken, '=')) != NULL) { ds_state = 1; /* Already in keyword state, close it out */ if (key_state > 0) { /* Add parameters to keyword */ if (!add_parameters(&r_keyword, &g_keyword, &b_keyword, key_params, key_state)) { Mceprintf("Error parsing keyword parameters %s=\n", in_keyword); return 1; } /* Add keyword to command */ strcat(&r_imgdisp, " "); strcat(&r_imgdisp, &r_keyword); strcat(&g_imgdisp, " "); strcat(&g_imgdisp, &g_keyword); strcat(&b_imgdisp, " "); strcat(&b_imgdisp, &b_keyword); } /* See if we have ECHO keyword */ if (!strcmp(cmdtoken, "ECH=Y") || !strcmp(cmdtoken, "ECHO=Y") || !strcmp(cmdtoken, "ECH=YE") || !strcmp(cmdtoken, "ECHO=YE") || !strcmp(cmdtoken, "ECH=YES") || !strcmp(cmdtoken, "ECHO=YES")) { strcpy(&r_keyword, ""); strcpy(&g_keyword, ""); strcpy(&b_keyword, ""); key_state = 0; do_echo = 1; continue; } /* Disallowed keywords */ else if (strstr(cmdtoken, "PAN=") != NULL || strstr(cmdtoken, "PANE=") != NULL || strstr(cmdtoken, "PANEL=") != NULL) { Mceprintf("Not compatible with PANEL=\n"); return 1; } else if (strstr(cmdtoken, "ALL=") != NULL) { Mceprintf("Not compatible with ALL=\n"); return 1; } else if (strstr(cmdtoken, "SEQ=") != NULL) { Mceprintf("Not compatible with SEQ=\n"); return 1; } else if (strstr(cmdtoken, "CYC=") != NULL || strstr(cmdtoken, "CYCL=") != NULL || strstr(cmdtoken, "CYCLE=") != NULL) { Mceprintf("Not compatible with CYCLE=\n"); return 1; } else if (strstr(cmdtoken, "REP=") != NULL || strstr(cmdtoken, "REPE=") != NULL || strstr(cmdtoken, "REPEA=") != NULL || strstr(cmdtoken, "REPEAT=") != NULL) { Mceprintf("Not compatible with REPEAT=\n"); return 1; } key_state = 1; strcpy(&in_keyword, cmdtoken); key_ptr = strchr(in_keyword, '='); *key_ptr = '\0'; val_ptr = key_ptr+1; strclean(clean_ptr, val_ptr); strcpy(key_params[0], clean_ptr); strcpy(&r_keyword, &in_keyword); strcat(&r_keyword, "="); strcpy(&g_keyword, &in_keyword); strcat(&g_keyword, "="); strcpy(&b_keyword, &in_keyword); strcat(&b_keyword, "="); continue; } /* In keyword */ if (key_state > 0) { strclean(clean_ptr, cmdtoken); strcpy(key_params[key_state], clean_ptr); key_state++; } } /* Add parameters to keyword */ if (key_state > 0) { if (!add_parameters(&r_keyword, &g_keyword, &b_keyword, key_params, key_state)) { Mceprintf("Error parsing keyword parameters %s=\n", in_keyword); return 1; } } /* Add keyword to command */ if (strlen(r_keyword) > 0) { strcat(&r_imgdisp, " "); strcat(&r_imgdisp, &r_keyword); strcpy(&r_keyword, ""); } if (strlen(g_keyword) > 0) { strcat(&g_imgdisp, " "); strcat(&g_imgdisp, &g_keyword); strcpy(&g_keyword, ""); } if (strlen(b_keyword) > 0) { strcat(&b_imgdisp, " "); strcat(&b_imgdisp, &b_keyword); strcpy(&b_keyword, ""); } } if (dest_frame == 0) { dest_frame = (int)McGetImageFrameNumber(); } dest_base = FRAME_BASE(dest_frame); frame_flags = FRAME_FLAGS(dest_base); /* Check for panels */ if (M0panel_x(dest_frame) > 1 || M0panel_y(dest_frame) > 1) { Mceprintf("Does not work with paneled frames (frame %d)\n", dest_frame); return 1; } /* See if this frame is being used */ if ((int)frame_flags->frame_type == 2 && frame_flags->gb_shm_key > 0) { shm_key = frame_flags->gb_shm_key; } else { M0FrameType(dest_frame, 0); } (void)Mcfsize(dest_frame, &dest_lines, &dest_elems); /************************** * Create RGB from frames * **************************/ if (r_frame >= 0 && g_frame >= 0 && b_frame >= 0) { (void)Mcfsize(r_frame, &r_lines, &r_elems); (void)Mcfsize(g_frame, &g_lines, &g_elems); (void)Mcfsize(b_frame, &b_lines, &b_elems); /* Red */ if (r_frame > 0) { if (M0panel_x(r_frame) > 1 || M0panel_y(r_frame) > 1) { Mceprintf("Does not work with paneled frames (frame %d)\n", r_frame); return 1; } if (do_echo) { Mcprintf("R: Frame %d (%dx%d)\n", r_frame, r_lines, r_elems); } Mcdprintf("R: Frame %d (%dx%d)\n", r_frame, r_lines, r_elems); if (n_frame < 0) { n_frame = r_frame; } if (r_lines != dest_lines || r_elems != dest_elems) { linele_ok = 0; } } else { if (do_echo) { Mcprintf("R: None\n"); } Mcdprintf("R: None\n"); } /* Green */ if (g_frame > 0) { if (M0panel_x(g_frame) > 1 || M0panel_y(g_frame) > 1) { Mceprintf("Does not work with paneled frames (frame %d)\n", g_frame); return 1; } if (do_echo) { Mcprintf("G: Frame %d (%dx%d)\n", g_frame, g_lines, g_elems); } Mcdprintf("G: Frame %d (%dx%d)\n", g_frame, g_lines, g_elems); if (n_frame < 0) { n_frame = g_frame; } if (g_lines != dest_lines || g_elems != dest_elems) { linele_ok = 0; } } else { if (do_echo) { Mcprintf("G: None\n"); } Mcdprintf("G: None\n"); } /* Blue */ if (b_frame > 0) { if (M0panel_x(b_frame) > 1 || M0panel_y(b_frame) > 1) { Mceprintf("Does not work with paneled frames (frame %d)\n", b_frame); return 1; } if (do_echo) { Mcprintf("B: Frame %d (%dx%d)\n", b_frame, b_lines, b_elems); } Mcdprintf("B: Frame %d (%dx%d)\n", b_frame, b_lines, b_elems); if (n_frame < 0) { n_frame = b_frame; } if (b_lines != dest_lines || b_elems != dest_elems) { linele_ok = 0; } } else { if (do_echo) { Mcprintf("B: None\n"); } Mcdprintf("B: None\n"); } Mcdprintf("Dest: %d (%dx%d)\n", dest_frame, dest_lines, dest_elems); if (linele_ok == 0) { Mceprintf("R, G, B frames must match destination dimensions\n"); return 1; } /* set references to R, G, B frames and copy frame dir/nav from first */ Mcdprintf("Copying frame directory/navigation from frame %d\n", n_frame); /* copy frame info to destination */ s_base = FRAME_BASE(n_frame); s_size = (size_t)(FRAME_BASE((int)(n_frame+1)) - s_base); memcpy(dest_base, s_base, s_size); /* copy frame directory to destination */ M0getfrm(n_frame, frameDirectory); /* Set SS=10 (Composite) */ /* frameDirectory[0] = 10; */ M0putfrm(dest_frame, frameDirectory); /* copy navigation to destination */ M0frtonv(n_frame, navBlock, 2560); M0nvtofr(dest_frame, navBlock, 2560); frame_flags->frame_type = (int)1; frame_flags->r_frame = r_frame; frame_flags->g_frame = g_frame; frame_flags->b_frame = b_frame; frame_flags->dirty = (int)-1; /* * Could keep frame_type = 1 and use frame reference * But we would rather copy data to shared memory * and treat everything the same down the line */ if (1) { /* Get shared memory segment for GB data */ s_base = FRAME_BASE(dest_frame); s_data = FRAME_DATA(s_base); s_size = dest_lines * dest_elems; gb_size = s_size * 2; if (shm_key < 0) { shm_key = M0shmget(gb_size, 0); } if (shm_key < 0) { Mceprintf("Unable to allocate shared memory for GB data\n"); return 1; } m0gbuc = (unsigned char *)M0shmat(shm_key, 0); if (m0gbuc < 0) { Mceprintf("Unable to connect to shared memory for GB data\n"); return 1; } Mcwrite("RGBFRMS.KEY",sizeof(int)*(dest_frame-1),sizeof(int),&shm_key); /* Load green into new shm location */ if (g_frame > 0) { Mcdprintf("Copying green frame data (%d) to shmkey %d\n", g_frame, shm_key); s_data = FRAME_DATA(FRAME_BASE(g_frame)); memcpy(m0gbuc, s_data, s_size); } else { memset(m0gbuc, 0, s_size); } /* Load blue into new shm location */ if (b_frame > 0) { Mcdprintf("Copying blue frame data (%d) to shmkey %d\n", b_frame, shm_key); s_data = FRAME_DATA(FRAME_BASE(b_frame)); memcpy(m0gbuc+s_size, s_data, s_size); } else { memset(m0gbuc+s_size, 0, s_size); } /* Load red into destination frame, then make RGB */ if (r_frame > 0) { Mcdprintf("Copying red frame data (%d) to frame %d\n", r_frame, dest_frame); s_data = FRAME_DATA(FRAME_BASE(r_frame)); memcpy(FRAME_DATA(dest_base), s_data, s_size); } else { memset(FRAME_DATA(dest_base), 0, s_size); } frame_flags->frame_type = (int)2; frame_flags->r_frame = dest_frame; frame_flags->g_frame = dest_frame; frame_flags->b_frame = dest_frame; frame_flags->gb_shm_key = shm_key; /* End copy to shared memory segment */ } } /**************************** * Create RGB from datasets * ****************************/ else if (strlen(r_imgdisp) > 0 || strlen(g_imgdisp) > 0 || strlen(b_imgdisp) > 0) { Mcdprintf("Using IMGDISP to request imagery\n"); make_imgdisp(&r_imgdisp, dest_frame); make_imgdisp(&g_imgdisp, dest_frame); make_imgdisp(&b_imgdisp, dest_frame); if (strlen(r_imgdisp) > 0) { Mcdprintf("R: %s\n", r_imgdisp); } else { Mcdprintf("R: None\n"); } if (strlen(g_imgdisp) > 0) { Mcdprintf("G: %s\n", g_imgdisp); } else { Mcdprintf("G: None\n"); } if (strlen(b_imgdisp) > 0) { Mcdprintf("B: %s\n", b_imgdisp); } else { Mcdprintf("B: None\n"); } Mcdprintf("Dest: %d (%dx%d)\n", dest_frame, dest_lines, dest_elems); /* Get shared memory segment for GB data */ s_base = FRAME_BASE(dest_frame); s_data = FRAME_DATA(s_base); s_size = dest_lines * dest_elems; gb_size = s_size * 2; if (shm_key < 0) { shm_key = M0shmget(gb_size, 0); } if (shm_key < 0) { Mceprintf("Unable to allocate shared memory for GB data\n"); return 1; } m0gbuc = (unsigned char *)M0shmat(shm_key, 0); if (m0gbuc < 0) { Mceprintf("Unable to connect to shared memory for GB data\n"); return 1; } Mcwrite("RGBFRMS.KEY",sizeof(int)*(dest_frame-1),sizeof(int),&shm_key); /* Load green into destination frame, then copy to new shm location */ if (strlen(g_imgdisp) > 0) { if (do_echo) { Mcprintf("G: %s\n", g_imgdisp); } ok = Mcskeyin(g_imgdisp); if (ok != 0) { Mceprintf("Error loading green data source\n"); return 1; } Mcdprintf("Copying green frame data to shmkey %d\n", shm_key); s_base = FRAME_BASE(dest_frame); s_data = FRAME_DATA(s_base); memcpy(m0gbuc, s_data, s_size); } else { if (do_echo) { Mcprintf("G: None\n"); } memset(m0gbuc, 0, s_size); } /* Load blue into destination frame, then copy to new shm location */ if (strlen(b_imgdisp) > 0) { if (do_echo) { Mcprintf("B: %s\n", b_imgdisp); } ok = Mcskeyin(b_imgdisp); if (ok != 0) { Mceprintf("Error loading blue data source\n"); return 1; } Mcdprintf("Copying blue frame data to shmkey %d\n", shm_key); s_base = FRAME_BASE(dest_frame); s_data = FRAME_DATA(s_base); memcpy(m0gbuc+s_size, s_data, s_size); } else { if (do_echo) { Mcprintf("B: None\n"); } memset(m0gbuc+s_size, 0, s_size); } /* Load red into destination frame, then make RGB */ if (strlen(r_imgdisp) > 0) { if (do_echo) { Mcprintf("R: %s\n", r_imgdisp); } ok = Mcskeyin(r_imgdisp); if (ok != 0) { Mceprintf("Error loading red data source\n"); return 1; } } else { if (do_echo) { Mcprintf("R: None\n"); } memset(s_data, 0, s_size); } /* Set SS=10 (Composite) */ /* M0getfrm(dest_frame, frameDirectory); frameDirectory[0] = 10; M0putfrm(dest_frame, frameDirectory); */ frame_flags->frame_type = (int)2; frame_flags->r_frame = dest_frame; frame_flags->g_frame = dest_frame; frame_flags->b_frame = dest_frame; frame_flags->gb_shm_key = shm_key; frame_flags->dirty = (int)-1; } /******************************* * Could not decide what to do * *******************************/ else { Mceprintf("Error parsing command line\n"); } sprintf(rgb_label, "FRMLABEL IMA=%d JUST=C \"(STYPE) (BAND) (DAYJ) AT (HHMMSS) UTC", dest_frame); ok = Mcskeyin(rgb_label); Mcprintf("RGBDISP: Done\n"); return 0; } int add_parameters(char *r_key, char *g_key, char *b_key, char params[7][64], int count) { /* Possible tailing character */ char *tailchar; tailchar = NULL; if (strlen(params[count-1]) == 1) { tailchar = params[count-1]; /* Special case for I, F for LIN.ELE */ if (strchr(tailchar, 'I') != NULL || strchr(tailchar, 'F') != NULL) { count--; } else { tailchar = NULL; } } if (count == 0) { return 1; } else if (count == 1) { strcat(r_key, params[0]); strcat(g_key, params[0]); strcat(b_key, params[0]); } else if (count == 2) { /* If there are any spaces, consider it no good */ if (strchr(params[0], ' ') != NULL || strchr(params[1], ' ') != NULL) { return 0; } strcat(r_key, params[0]); strcat(r_key, " "); strcat(r_key, params[1]); strcat(g_key, params[0]); strcat(g_key, " "); strcat(g_key, params[1]); strcat(b_key, params[0]); strcat(b_key, " "); strcat(b_key, params[1]); } else if (count == 3) { strcat(r_key, params[0]); strcat(g_key, params[1]); strcat(b_key, params[2]); } else if (count == 6) { strcat(r_key, params[0]); strcat(r_key, " "); strcat(r_key, params[1]); strcat(g_key, params[2]); strcat(g_key, " "); strcat(g_key, params[3]); strcat(b_key, params[4]); strcat(b_key, " "); strcat(b_key, params[5]); } else { return 0; } if (tailchar != NULL) { strcat(r_key, " "); strcat(r_key, tailchar); strcat(g_key, " "); strcat(g_key, tailchar); strcat(b_key, " "); strcat(b_key, tailchar); } return 1; } void make_imgdisp(char *params, int dest_frame) { const char *cmdsep; int wordcount; char imgdisp[1024]; char frm[8]; char *cmdtoken; cmdsep = " "; wordcount = 0; memset(imgdisp, '\0', sizeof(imgdisp)); sprintf(frm, "%d", dest_frame); strcpy(&imgdisp, "IMGDISP "); cmdtoken = strtok(params, cmdsep); if (strlen(cmdtoken) == 1 && strchr(params, '0') != NULL) { strcpy(params, ""); return; } strcat(&imgdisp, cmdtoken); strcat(&imgdisp, " "); strcat(&imgdisp, frm); cmdtoken = strtok(NULL, cmdsep); while (cmdtoken != NULL) { strcat(&imgdisp, " "); strcat(&imgdisp, cmdtoken); cmdtoken = strtok(NULL, cmdsep); } strcat(&imgdisp, " RGB=1"); strcpy(params, imgdisp); } void strclean(char clean_ptr[], char *val_ptr) { strcpy(clean_ptr, val_ptr); int offset = 0; int length = strlen(clean_ptr); if (clean_ptr[0] == '\'') { offset = 1; length--; } if (clean_ptr[length] == '\'') { length--; } strncpy(clean_ptr, val_ptr+offset, length); clean_ptr[length] = '\0'; } char *strtokqt(char *input, char *delimit) { static char qt = '\''; static char *token = NULL; char *lead = NULL; char *block = NULL; int iBlock = 0; if (input != NULL) { token = input; lead = input; } else { lead = token; if (*token == '\0') { lead = NULL; } } while (*token != '\0') { if (iBlock) { if (qt == *token) { iBlock = 0; } token++; continue; } if (qt == *token) { iBlock = 1; token++; continue; } if (strchr(delimit, *token) != NULL) { *token = '\0'; token++; break; } token++; } return lead; }