surface& operator=(surface&& s) { free_surface(); surface_ = s.surface_; s.surface_ = nullptr; return *this; }
void free_ri_surface(struct ris_t *ris) { free_string(ris->filename); free_surface(ris->surface); LL_REMOVE(struct ris_t, &ris0, ris); }
static GstFlowReturn gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task) { GstVideoDecoder *decoder = GST_VIDEO_DECODER (thiz); GstFlowReturn flow; GstVideoCodecFrame *frame; MsdkSurface *surface; mfxStatus status; GList *l; if (G_LIKELY (task->sync_point)) { status = MFXVideoCORE_SyncOperation (gst_msdk_context_get_session (thiz->context), task->sync_point, 300000); if (status != MFX_ERR_NONE) { GST_ERROR_OBJECT (thiz, "failed to do sync operation"); return GST_FLOW_ERROR; } } if (G_LIKELY (task->sync_point || (task->surface && task->decode_only))) { gboolean decode_only = task->decode_only; frame = gst_msdkdec_get_oldest_frame (decoder); l = g_list_find_custom (thiz->decoded_msdk_surfaces, task->surface, _find_msdk_surface); if (l) { surface = l->data; } else { GST_ERROR_OBJECT (thiz, "Couldn't find the cached MSDK surface"); return GST_FLOW_ERROR; } if (G_LIKELY (frame)) { if (G_LIKELY (surface->copy.buffer == NULL)) { frame->output_buffer = gst_buffer_ref (surface->buf); } else { gst_video_frame_copy (&surface->copy, &surface->data); frame->output_buffer = gst_buffer_ref (surface->copy.buffer); } } free_surface (thiz, surface); task->sync_point = NULL; task->surface = NULL; task->decode_only = FALSE; if (!frame) return GST_FLOW_FLUSHING; gst_video_codec_frame_unref (frame); if (decode_only) GST_VIDEO_CODEC_FRAME_SET_DECODE_ONLY (frame); flow = gst_video_decoder_finish_frame (decoder, frame); return flow; } return GST_FLOW_OK; }
void set_ri_surface_multiplier(float m) { ris_multiplier = m; struct ris_t *cris = ris0; while(cris) { free_surface(cris->surface); struct surface_t *temp = read_png_surface(cris->filename->text); cris->surface = resize(temp, temp->width * ris_multiplier, temp->height * ris_multiplier); free_surface(temp); cris = cris->next; } }
void kill_ris() { while(ris0) { free_string(ris0->filename); free_surface(ris0->surface); LL_REMOVE(struct ris_t, &ris0, ris0); } }
static void release_msdk_surfaces (GstMsdkDec * thiz) { GList *l; MsdkSurface *surface; for (l = thiz->decoded_msdk_surfaces; l; l = l->next) { surface = l->data; free_surface (thiz, surface); } }
// seg001:0C94 void __pascal far expired() { if (!demo_mode) { if(offscreen_surface) free_surface(offscreen_surface); // missing in original offscreen_surface = NULL; clear_screen_and_sounds(); offscreen_surface = make_offscreen_buffer(&screen_rect); load_intro(1, &time_expired, 1); } start_level = 0; start_game(); }
struct surface_t *leave_main_lock_and_resize_surface(struct surface_t *in_surface, int width, int height) { struct surface_t *duplicate, *resized; duplicate = duplicate_surface(in_surface); leave_main_lock(); resized = resize(duplicate, width, height); free_surface(duplicate); return resized; }
struct surface_t *leave_main_lock_and_rotate_surface(struct surface_t *in_surface, int scale_width, int scale_height, double theta) { struct surface_t *duplicate, *rotated; duplicate = duplicate_surface(in_surface); leave_main_lock(); rotated = rotate_surface(duplicate, scale_width, scale_height, theta); free_surface(duplicate); return rotated; }
void st::_app::sdl_poll::run() { SDL_Surface* image = NULL; // Could, should this be a member? Should I just have a // standard loop that I can start up. I'll refactor this // soonish. bool quit = false; initialize_screen( "Event Test" ); image = load_image( "x.png" ); apply_surface(0, 0, image); flip(); // Will need to rework event loop somehow... start(); free_surface( image ); }
struct ris_t *load_ri_surface(char *filename) { struct ris_t ris; ris.filename = new_string_text(filename); struct surface_t *temp = read_png_surface(filename); ris.surface = resize(temp, temp->width * ris_multiplier, temp->height * ris_multiplier); free_surface(temp); LL_ADD(struct ris_t, &ris0, &ris); return ris0; }
void st::_app::lesson4::run() { SDL_Surface* image = NULL; // Could, should this be a member? Should I just have a // standard loop that I can start up. I'll refactor this // soonish. SDL_Event event; bool quit = false; initialize_screen( "Event Test" ); image = load_image( "x.png" ); apply_surface(0, 0, image); flip(); // Will need to rework event loop somehow... while ( quit == false ) { while ( SDL_PollEvent(&event) ) { if ( event.type == SDL_QUIT ) { quit = true; } } } free_surface( image ); }
void free_scene (struct msscene *ms) { struct square *squares; struct molecule *head_molecule; struct surface *head_srf; struct material_table *table; struct color_ramp *head_ramp; struct object_scheme *scheme; struct surface *srf, *next_srf; struct color_ramp *rmp, *next_rmp; struct molecule *mol, *next_mol; head_molecule = ms -> head_molecule; head_ramp = ms -> head_ramp; table = ms -> table; squares = ms -> squares; for (mol = head_molecule; mol != NULL; mol = next_mol) { next_mol = mol -> next; head_srf = mol -> head_surface; for (srf = head_srf; srf != NULL; srf = next_srf) { next_srf = srf -> next; scheme = srf -> scheme; if (scheme != NULL) { if (scheme -> atom_opacities != NULL) free_doubles (scheme -> atom_opacities, 0, ATOM_OPACITIES); if (scheme -> atom_colors != NULL) free_longs (scheme -> atom_colors, 0, ATOM_COLORS); free_object (OBJECT_SCHEME, (short *) (srf -> scheme)); if (error()) return; } clear_pqms (srf); if (error()) return; free_surface (srf); if (error()) return; free_phn (srf); if (error()) return; free_object (SURFACE, (short *) srf); if (error()) return; } if (mol -> atom_alphas != NULL) free_doubles (mol -> atom_alphas, 0, ATOM_ALPHAS); free_object (MOLECULE, (short *) mol); if (error()) return; } for (srf = ms -> this_srf; srf != NULL; srf = next_srf) { next_srf = srf -> next; clear_pqms (srf); if (error()) return; free_surface (srf); if (error()) return; free_phn (srf); if (error()) return; free_object (SURFACE, (short *) srf); if (error()) return; } for (rmp = head_ramp; rmp != NULL; rmp = next_rmp) { next_rmp = rmp -> next; free_object (COLOR_RAMP, (short *) rmp); if (error()) return; } free_object (MATERIAL_TABLE, (short *) (ms -> table)); free_object (MSSCENE, (short *) ms); }
// seg001:09D7 void __pascal far end_sequence() { peel_type* peel; short bgcolor; short color; rect_type rect; short hof_index; short i; color = 0; bgcolor = 15; load_intro(1, &end_sequence_anim, 1); clear_screen_and_sounds(); load_opt_sounds(sound_56_ending_music, sound_56_ending_music); // winning theme play_sound_from_buffer(sound_pointers[sound_56_ending_music]); // winning theme if(offscreen_surface) free_surface(offscreen_surface); // missing in original offscreen_surface = make_offscreen_buffer(&screen_rect); load_title_images(0); current_target_surface = offscreen_surface; draw_image_2(0 /*story frame*/, chtab_title40, 0, 0, 0); draw_image_2(3 /*The tyrant Jaffar*/, chtab_title40, 24, 25, get_text_color(15, color_15_brightwhite, 0x800)); fade_in_2(offscreen_surface, 0x800); pop_wait(timer_0, 900); start_timer(timer_0, 240); draw_image_2(0 /*main title image*/, chtab_title50, 0, 0, 0); transition_ltr(); do_wait(timer_0); for (hof_index = 0; hof_index < hof_count; ++hof_index) { if (hof[hof_index].min < rem_min || (hof[hof_index].min == rem_min && hof[hof_index].tick < rem_tick) ) break; } if (hof_index < MAX_HOF_COUNT && hof_index <= hof_count) { fade_out_2(0x1000); for (i = 5; hof_index + 1 <= i; --i) { hof[i] = hof[i - 1]; } hof[i].name[0] = 0; hof[i].min = rem_min; hof[i].tick = rem_tick; if (hof_count < MAX_HOF_COUNT) { ++hof_count; } draw_image_2(0 /*story frame*/, chtab_title40, 0, 0, 0); draw_image_2(3 /*Prince Of Persia*/, chtab_title50, 24, 24, blitters_10h_transp); show_hof(); offset4_rect_add(&rect, &hof_rects[hof_index], -4, -1, -40, -1); peel = read_peel_from_screen(&rect); if (graphics_mode == gmMcgaVga) { color = 0xBE; bgcolor = 0xB7; } draw_rect(&rect, bgcolor); fade_in_2(offscreen_surface, 0x1800); current_target_surface = onscreen_surface_; while(input_str(&rect, hof[hof_index].name, 24, "", 0, 4, color, bgcolor) <= 0); restore_peel(peel); show_hof_text(&hof_rects[hof_index], -1, 0, hof[hof_index].name); hof_write(); pop_wait(timer_0, 120); current_target_surface = offscreen_surface; draw_image_2(0 /*main title image*/, chtab_title50, 0, 0, blitters_0_no_transp); transition_ltr(); } while (check_sound_playing() && !key_test_quit()) idle(); fade_out_2(0x1000); start_level = 0; start_game(); }
static GstFlowReturn gst_msdkdec_drain (GstVideoDecoder * decoder) { GstMsdkDec *thiz = GST_MSDKDEC (decoder); GstFlowReturn flow; GstBuffer *buffer; MsdkDecTask *task; MsdkSurface *surface = NULL; mfxSession session; mfxStatus status; guint i; if (!thiz->initialized) return GST_FLOW_OK; session = gst_msdk_context_get_session (thiz->context); for (;;) { task = &g_array_index (thiz->tasks, MsdkDecTask, thiz->next_task); if ((flow = gst_msdkdec_finish_task (thiz, task)) != GST_FLOW_OK) { if (flow != GST_FLOW_FLUSHING) GST_WARNING_OBJECT (decoder, "failed to finish the task %p, but keep draining for the remaining frames", task); } if (!surface) { flow = allocate_output_buffer (thiz, &buffer); if (flow != GST_FLOW_OK) return flow; surface = get_surface (thiz, buffer); if (!surface) return GST_FLOW_ERROR; } status = MFXVideoDECODE_DecodeFrameAsync (session, NULL, surface->surface, &task->surface, &task->sync_point); if (G_LIKELY (status == MFX_ERR_NONE)) { thiz->next_task = (thiz->next_task + 1) % thiz->tasks->len; if (surface->surface->Data.Locked == 0) free_surface (thiz, surface); surface = NULL; } else if (status == MFX_WRN_VIDEO_PARAM_CHANGED) { continue; } else if (status == MFX_WRN_DEVICE_BUSY) { /* If device is busy, wait 1ms and retry, as per MSDK's recomendation */ g_usleep (1000); /* If the current surface is still busy, we should do sync oepration * then tries to decode again */ thiz->next_task = (thiz->next_task + 1) % thiz->tasks->len; } else if (status == MFX_ERR_MORE_DATA) { break; } else if (status == MFX_ERR_MORE_SURFACE) { surface = NULL; continue; } else if (status < MFX_ERR_NONE) return GST_FLOW_ERROR; } if (surface) free_surface (thiz, surface); for (i = 0; i < thiz->tasks->len; i++) { task = &g_array_index (thiz->tasks, MsdkDecTask, thiz->next_task); gst_msdkdec_finish_task (thiz, task); thiz->next_task = (thiz->next_task + 1) % thiz->tasks->len; } release_msdk_surfaces (thiz); return GST_FLOW_OK; }
static GstFlowReturn gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame) { GstMsdkDec *thiz = GST_MSDKDEC (decoder); GstMsdkDecClass *klass = GST_MSDKDEC_GET_CLASS (thiz); GstFlowReturn flow; GstBuffer *buffer, *input_buffer = NULL; GstVideoInfo alloc_info; MsdkDecTask *task = NULL; mfxBitstream bitstream; MsdkSurface *surface = NULL; mfxSession session; mfxStatus status; GstMapInfo map_info; guint i; gsize data_size; gboolean hard_reset = FALSE; /* configure the subclass in order to fill the CodecID field of * mfxVideoParam and also to load the PluginID for some of the * codecs which is mandatory to invoke the * MFXVideoDECODE_DecodeHeader API. * * For non packetized formats (currently only vc1), there * could be headers received as codec_data which are not available * instream and in that case subclass implementation will * push it to the internal adapter. We invoke the subclass configure * well early to make sure the codec_data received has been correctly * pushed to the adapter by the subclasses before doing * the DecodeHeader() later on */ if (!thiz->initialized || thiz->do_renego) { /* Clear the internal adapter in renegotiation for non-packetized * formats */ if (!thiz->is_packetized) gst_adapter_clear (thiz->adapter); if (!klass->configure || !klass->configure (thiz)) { flow = GST_FLOW_OK; goto error; } } /* Current frame-codec could be pushed and released before this * function ends -- because msdkdec pushes the oldest frame, * according its PTS, and it could be this very same frame-codec * among others pending frame-codecs. * * Instead of copying the input data into the mfxBitstream, let's * keep an extra reference to frame-codec's input buffer */ input_buffer = gst_buffer_ref (frame->input_buffer); if (!gst_buffer_map (input_buffer, &map_info, GST_MAP_READ)) { gst_buffer_unref (input_buffer); return GST_FLOW_ERROR; } memset (&bitstream, 0, sizeof (bitstream)); if (thiz->is_packetized) { /* Packetized stream: We prefer to have a parser as connected upstream * element to the decoder */ bitstream.Data = map_info.data; bitstream.DataLength = map_info.size; bitstream.MaxLength = map_info.size; bitstream.DataFlag = MFX_BITSTREAM_COMPLETE_FRAME; } else { /* Non packetized streams: eg: vc1 advanced profile with per buffer bdu */ gst_adapter_push (thiz->adapter, gst_buffer_ref (input_buffer)); data_size = gst_adapter_available (thiz->adapter); bitstream.Data = (mfxU8 *) gst_adapter_map (thiz->adapter, data_size); bitstream.DataLength = (mfxU32) data_size; bitstream.MaxLength = bitstream.DataLength; } GST_INFO_OBJECT (thiz, "mfxBitStream=> DataLength:%d DataOffset:%d MaxLength:%d", bitstream.DataLength, bitstream.DataOffset, bitstream.MaxLength); session = gst_msdk_context_get_session (thiz->context); if (!thiz->initialized || thiz->do_renego) { /* gstreamer caps will not bring all the necessary parameters * required for optimal decode configuration. For eg: the required numbers * of surfaces to be allocated can be calculated based on H264 SEI header * and this information can't be retrieved from the negotiated caps. * So instead of introducing the codecparser dependency to parse the headers * inside msdk plugin, we simply use the mfx apis to extract header information */ status = MFXVideoDECODE_DecodeHeader (session, &bitstream, &thiz->param); if (status == MFX_ERR_MORE_DATA) { flow = GST_FLOW_OK; goto done; } if (!thiz->initialized) hard_reset = TRUE; else if (thiz->allocation_caps) { gst_video_info_from_caps (&alloc_info, thiz->allocation_caps); /* Check whether we need complete reset for dynamic resolution change */ if (thiz->param.mfx.FrameInfo.Width > GST_VIDEO_INFO_WIDTH (&alloc_info) || thiz->param.mfx.FrameInfo.Height > GST_VIDEO_INFO_HEIGHT (&alloc_info)) hard_reset = TRUE; } /* if subclass requested for the force reset */ if (thiz->force_reset_on_res_change) hard_reset = TRUE; /* Config changed dynamically and we are going to do a full reset, * this will unref the input frame which has the new configuration. * Keep a ref to the input_frame to keep it alive */ if (thiz->initialized && thiz->do_renego) gst_video_codec_frame_ref (frame); if (!gst_msdkdec_negotiate (thiz, hard_reset)) { GST_ELEMENT_ERROR (thiz, CORE, NEGOTIATION, ("Could not negotiate the stream"), (NULL)); flow = GST_FLOW_ERROR; goto error; } } for (;;) { task = &g_array_index (thiz->tasks, MsdkDecTask, thiz->next_task); flow = gst_msdkdec_finish_task (thiz, task); if (flow != GST_FLOW_OK) goto error; if (!surface) { flow = allocate_output_buffer (thiz, &buffer); if (flow != GST_FLOW_OK) goto error; surface = get_surface (thiz, buffer); if (!surface) { /* Can't get a surface for some reason, finish tasks to see if a surface becomes available. */ for (i = 0; i < thiz->tasks->len - 1; i++) { thiz->next_task = (thiz->next_task + 1) % thiz->tasks->len; task = &g_array_index (thiz->tasks, MsdkDecTask, thiz->next_task); flow = gst_msdkdec_finish_task (thiz, task); if (flow != GST_FLOW_OK) goto error; surface = get_surface (thiz, buffer); if (surface) break; } if (!surface) { GST_ERROR_OBJECT (thiz, "Couldn't get a surface"); flow = GST_FLOW_ERROR; goto error; } } } status = MFXVideoDECODE_DecodeFrameAsync (session, &bitstream, surface->surface, &task->surface, &task->sync_point); /* media-sdk requires complete reset since the surface is inadaquate to * do further decoding */ if (status == MFX_ERR_INCOMPATIBLE_VIDEO_PARAM) { /* Requires memory re-allocation, do a hard reset */ if (!gst_msdkdec_negotiate (thiz, TRUE)) goto error; status = MFXVideoDECODE_DecodeFrameAsync (session, &bitstream, surface->surface, &task->surface, &task->sync_point); } if (G_LIKELY (status == MFX_ERR_NONE) || (status == MFX_WRN_VIDEO_PARAM_CHANGED)) { thiz->next_task = (thiz->next_task + 1) % thiz->tasks->len; if (surface->surface->Data.Locked > 0 || !thiz->use_video_memory) surface = NULL; if (bitstream.DataLength == 0) { flow = GST_FLOW_OK; break; } } else if (status == MFX_ERR_MORE_DATA) { if (task->surface) { task->decode_only = TRUE; thiz->next_task = (thiz->next_task + 1) % thiz->tasks->len; } if (surface->surface->Data.Locked > 0) surface = NULL; flow = GST_VIDEO_DECODER_FLOW_NEED_DATA; break; } else if (status == MFX_ERR_MORE_SURFACE) { surface = NULL; continue; } else if (status == MFX_WRN_DEVICE_BUSY) { /* If device is busy, wait 1ms and retry, as per MSDK's recomendation */ g_usleep (1000); /* If the current surface is still busy, we should do sync oepration * then tries to decode again */ thiz->next_task = (thiz->next_task + 1) % thiz->tasks->len; } else if (status < MFX_ERR_NONE) { GST_ERROR_OBJECT (thiz, "DecodeFrameAsync failed (%s)", msdk_status_to_string (status)); flow = GST_FLOW_ERROR; break; } } if (!thiz->is_packetized) { /* flush out the data which is already consumed by msdk */ gst_adapter_flush (thiz->adapter, bitstream.DataOffset); flow = GST_FLOW_OK; } done: if (surface) free_surface (thiz, surface); gst_buffer_unmap (input_buffer, &map_info); gst_buffer_unref (input_buffer); return flow; error: if (input_buffer) { gst_buffer_unmap (input_buffer, &map_info); gst_buffer_unref (input_buffer); } gst_video_decoder_drop_frame (decoder, frame); return flow; }
~surface() { free_surface(); }
void assign_surface_internal(SDL_Surface* surf) { add_surface_ref(surf); // Needs to be done before assignment to avoid corruption on "a = a;" free_surface(); surface_ = surf; }
// seg000:17E6 void __pascal far show_title() { word textcolor; load_opt_sounds(sound_50_story_2_princess, sound_55_story_1_absence); // main theme, story, princess door textcolor = get_text_color(15, color_15_white, 0x800); dont_reset_time = 0; if(offscreen_surface) free_surface(offscreen_surface); // missing in original offscreen_surface = make_offscreen_buffer(&screen_rect); load_title_images(1); current_target_surface = offscreen_surface; do_wait(timer_0); draw_image_2(0 /*main title image*/, chtab_title50, 0, 0, blitters_0_no_transp); fade_in_2(offscreen_surface, 0x1000); //STUB method_1_blit_rect(onscreen_surface_, offscreen_surface, &screen_rect, &screen_rect, blitters_0_no_transp); play_sound_from_buffer(sound_pointers[54]); // main theme start_timer(timer_0, 0x82); draw_image_2(1 /*Broderbund Software presents*/, chtab_title50, 96, 106, blitters_0_no_transp); do_wait(timer_0); start_timer(timer_0,0xCD); method_1_blit_rect(onscreen_surface_, offscreen_surface, &rect_titles, &rect_titles, blitters_0_no_transp); draw_image_2(0 /*main title image*/, chtab_title50, 0, 0, blitters_0_no_transp); do_wait(timer_0); start_timer(timer_0,0x41); method_1_blit_rect(onscreen_surface_, offscreen_surface, &rect_titles, &rect_titles, blitters_0_no_transp); draw_image_2(0 /*main title image*/, chtab_title50, 0, 0, blitters_0_no_transp); draw_image_2(2 /*a game by Jordan Mechner*/, chtab_title50, 96, 122, blitters_0_no_transp); do_wait(timer_0); start_timer(timer_0,0x10E); method_1_blit_rect(onscreen_surface_, offscreen_surface, &rect_titles, &rect_titles, blitters_0_no_transp); draw_image_2(0 /*main title image*/, chtab_title50, 0, 0, blitters_0_no_transp); do_wait(timer_0); start_timer(timer_0,0xEB); method_1_blit_rect(onscreen_surface_, offscreen_surface, &rect_titles, &rect_titles, blitters_0_no_transp); draw_image_2(0 /*main title image*/, chtab_title50, 0, 0, blitters_0_no_transp); draw_image_2(3 /*Prince Of Persia*/, chtab_title50, 24, 107, blitters_10h_transp); draw_image_2(4 /*Copyright 1990 Jordan Mechner*/, chtab_title50, 48, 184, blitters_0_no_transp); do_wait(timer_0); method_1_blit_rect(onscreen_surface_, offscreen_surface, &rect_titles, &rect_titles, blitters_0_no_transp); draw_image_2(0 /*story frame*/, chtab_title40, 0, 0, blitters_0_no_transp); draw_image_2(1 /*In the Sultan's absence*/, chtab_title40, 24, 25, textcolor); current_target_surface = onscreen_surface_; while (check_sound_playing()) { idle(); do_paused(); } // method_1_blit_rect(onscreen_surface_, offscreen_surface, &screen_rect, &screen_rect, blitters_0_no_transp); play_sound_from_buffer(sound_pointers[sound_55_story_1_absence]); // story 1: In the absence transition_ltr(); pop_wait(timer_0, 0x258); fade_out_2(0x800); release_title_images(); load_intro(0, &pv_scene, 0); load_title_images(1); current_target_surface = offscreen_surface; draw_image_2(0 /*story frame*/, chtab_title40, 0, 0, blitters_0_no_transp); draw_image_2(2 /*Marry Jaffar*/, chtab_title40, 24, 25, textcolor); fade_in_2(offscreen_surface, 0x800); draw_image_2(0 /*main title image*/, chtab_title50, 0, 0, blitters_0_no_transp); draw_image_2(3 /*Prince Of Persia*/, chtab_title50, 24, 107, blitters_10h_transp); draw_image_2(4 /*Copyright 1990 Jordan Mechner*/, chtab_title50, 48, 184, blitters_0_no_transp); while (check_sound_playing()) { idle(); do_paused(); } transition_ltr(); pop_wait(timer_0, 0x78); draw_image_2(0 /*story frame*/, chtab_title40, 0, 0, blitters_0_no_transp); draw_image_2(4 /*credits*/, chtab_title40, 24, 26, textcolor); transition_ltr(); pop_wait(timer_0, 0x168); if (hof_count) { draw_image_2(0 /*story frame*/, chtab_title40, 0, 0, blitters_0_no_transp); draw_image_2(3 /*Prince Of Persia*/, chtab_title50, 24, 24, blitters_10h_transp); show_hof(); transition_ltr(); pop_wait(timer_0, 0xF0); } current_target_surface = onscreen_surface_; while (check_sound_playing()) { idle(); do_paused(); } fade_out_2(0x1800); free_surface(offscreen_surface); offscreen_surface = NULL; // added release_title_images(); init_game(0); }
int NLLoc ( // calling parameters char *pid_main, // CUSTOM_ETH only: snap id char *fn_control_main, // NLLoc control file: full path and name (set to NULL if *param_line_array not NULL) char **param_line_array, // array of NLLoc control file lines (set to NULL if fn_control_main not NULL) int n_param_lines, // number of elements (parameter lines) in array param_line_array (use 0 if fn_control_main not NULL) char **obs_line_array, // array of observations file lines (set to NULL if obs file name is read from NLLoc control file) int n_obs_lines, // number of elements (obs file lines) in array obs_line_array (set to 0 if obs file name is read from NLLoc control file) int return_locations, // if = 1, return Locations with basic information (HypoDesc* phypo, ArrivalDesc* parrivals, int narrivals, GridDesc* pgrid int return_oct_tree_grid, // if = 1 and LOCSEARCH OCT used, includes location probabily density oct-tree structure in Locations (Tree3D* poctTree) int return_scatter_sample, // if = 1, includes location location scatter sample data in Locations (float* pscatterSample) // returned parameters LocNode **ploc_list_head // pointer to pointer to head of list of LocNodes containing Location's for located events (see phaseloclist.h), *ploc_list_head must be initialized to NULL on first call to NLLoc() ) { int istat, n; int i_end_of_input, iLocated; int narr, ngrid, nObsFile; int numArrivalsIgnore, numSArrivalsLocation; int numArrivalsReject; int maxArrExceeded = 0; int n_file_root_count = 1; char fn_root_out[FILENAME_MAX], fname[FILENAME_MAX], fn_root_out_last[FILENAME_MAX]; char sys_command[MAXLINE_LONG]; char *chr; FILE *fp_obs = NULL, *fpio; char *ppath; int return_value = EXIT_NORMAL; /* set program name */ strcpy(prog_name, PNAME); // DD nll_mode = MODE_ABSOLUTE; /* set constants */ SetConstants(); NumLocGrids = 0; NumEvents = NumEventsLocated = NumLocationsCompleted = 0; NumCompDesc = 0; NumLocAlias = 0; NumLocExclude = 0; NumTimeDelays = 0; NumPhaseID = 0; DistStaGridMax = 0.0; MinNumArrLoc = 0; MinNumSArrLoc = 0; MaxNumArrLoc = MAX_NUM_ARRIVALS; FixOriginTimeFlag = 0; Scatter.npts = -1; for (n = 0; n < MAX_NUM_MAG_METHODS; n++) Magnitude[n].type = MAG_UNDEF; NumMagnitudeMethods = 0; ApplyCrustElevCorrFlag = 0; MinDistCrustElevCorr = 2.0; // deg ApplyElevCorrFlag = 0; NumTimeDelaySurface = 0; topo_surface_index = -1; iRejectDuplicateArrivals = 1; strcpy(fn_root_out_last, ""); ; // Arrival prior weighting (NLL_FORMAT_VER_2) iUseArrivalPriorWeights = 1; // station distance weighting iSetStationDistributionWeights = 0; stationDistributionWeightCutoff = -1; // GridMemLib MaxNum3DGridMemory = -1; GridMemList = NULL; GridMemListSize = 0; GridMemListNumElements = 0; // otime limits OtimeLimitList = NULL; NumOtimeLimit = 0; // GLOBAL NumSources = 0; NumStations = 0; // Gauss2 iUseGauss2 = 0; // output iSaveNLLocEvent = iSaveNLLocSum = iSaveHypo71Event = iSaveHypo71Sum = iSaveHypoEllEvent = iSaveHypoEllSum = iSaveHypoInvSum = iSaveHypoInvY2KArc = iSaveAlberto4Sum = iSaveNLLocOctree = iSaveNone = 0; /* open control file */ if (fn_control_main != NULL) { strcpy(fn_control, fn_control_main); if ((fp_control = fopen(fn_control, "r")) == NULL) { nll_puterr("FATAL ERROR: opening control file."); return_value = EXIT_ERROR_FILEIO; goto cleanup_return; } else { NumFilesOpen++; } } else { fp_control = NULL; } #ifdef CUSTOM_ETH /* SH 02/27/2004 added snap_pid */ strcpy(snap_pid, pid_main); /* SH 02AUG2004 not needed any more // AJL 20040527 added snap param file if (argc > 3) strcpy(snap_param_file, argv[3]); else strcpy(snap_param_file, "snap_param.txt"); */ #endif /* read NLLoc control statements from control file */ if ((istat = ReadNLLoc_Input(fp_control, param_line_array, n_param_lines)) < 0) { nll_puterr("FATAL ERROR: reading control file."); return_value = EXIT_ERROR_FILEIO; goto cleanup_return; } if (fp_control != NULL) { fclose(fp_control); NumFilesOpen--; } /* read observation lines into memory stream (must read control file first) */ char *bp_memory_stream = NULL; if (n_obs_lines > 0) { #ifdef _GNU_SOURCE size_t memory_stream_size; FILE *fp_memory_stream = NULL; // read lines into memory memory stream fp_memory_stream = open_memstream(&bp_memory_stream, &memory_stream_size); if (fp_memory_stream == NULL) { nll_puterr("FATAL ERROR: Cannot pass observations file lines as string array to NLLoc function: GNU C library extensions needed to support memory streams (function open_memstream)."); return_value = EXIT_ERROR_MEMORY; goto cleanup_return; } for (n = 0; n < n_obs_lines; n++) { fprintf(fp_memory_stream, "%s", obs_line_array[n]); /*DEBUG*///printf("%s", obs_line_array[n]); } fclose(fp_memory_stream); // fp_obs = fmemopen(bp_memory_stream, memory_stream_size, "r"); NumObsFiles = 1; #else nll_puterr("FATAL ERROR: Cannot pass observations file lines as string array to NLLoc function: GNU C library extensions needed to support memory streams (function open_memstream(); see compiler define _GNU_SOURCE)."); return_value = EXIT_ERROR_MEMORY; goto cleanup_return; #endif } // get path to output files strcpy(f_outpath, fn_path_output); if ((ppath = strrchr(f_outpath, '/')) != NULL || (ppath = strrchr(f_outpath, '\\')) != NULL) *(ppath + 1) = '\0'; else strcpy(f_outpath, ""); // copy control file to output directory if (!iSaveNone && fp_control != NULL) { chr = strrchr(fn_control, '/'); if (chr != NULL) strcpy(fname, chr + 1); else strcpy(fname, fn_control); sprintf(sys_command, "cp -p %s %s_%s", fn_control, fn_path_output, fname); system(sys_command); sprintf(sys_command, "cp -p %s %slast.in", fn_control, f_outpath); system(sys_command); //printf("sys_command: %s\n", sys_command); } /* convert source location coordinates */ istat = ConvertSourceLoc(0, Source, NumSources, 1, 1); /* initialize random number generator */ SRAND_FUNC(RandomNumSeed); if (message_flag >= 4) test_rand_int(); /* open summary output file */ if (!iSaveNone) { if ((istat = OpenSummaryFiles(fn_path_output, "grid")) < 0) { nll_puterr("FATAL ERROR: opening hypocenter summary files."); return_value = EXIT_ERROR_FILEIO; goto cleanup_return; } } // 20101005 AJL // open velocity files if needed fp_model_grid_P = fp_model_hdr_P = NULL; fp_model_grid_S = fp_model_hdr_S = NULL; if (LocMethod == METH_OT_STACK) { sprintf(fname, "%s.%s", fn_loc_grids, "P.mod"); if ((istat = OpenGrid3dFile(fname, &fp_model_grid_P, &fp_model_hdr_P, &model_grid_P, " ", NULL, iSwapBytesOnInput)) < 0) { sprintf(MsgStr, "WARNING: LocMethod == OT_STACK, but cannot open velocity model file %s.*", fname); nll_putmsg(1, MsgStr); } else { sprintf(MsgStr, "INFO: LocMethod == OT_STACK, sucessfully opened velocity model file %s.*", fname); nll_putmsg(1, MsgStr); } sprintf(fname, "%s.%s", fn_loc_grids, "S.mod"); if ((istat = OpenGrid3dFile(fname, &fp_model_grid_S, &fp_model_hdr_S, &model_grid_S, " ", NULL, iSwapBytesOnInput)) < 0) { sprintf(MsgStr, "WARNING: LocMethod == OT_STACK, but cannot open velocity model file %s.*", fname); nll_putmsg(1, MsgStr); } else { sprintf(MsgStr, "INFO: LocMethod == OT_STACK, sucessfully opened velocity model file %s.*", fname); nll_putmsg(1, MsgStr); } } /* perform location for each observation file */ for (nObsFile = 0; nObsFile < NumObsFiles; nObsFile++) { i_end_of_input = 0; nll_putmsg(2, ""); sprintf(MsgStr, "... Reading observation file %s", fn_loc_obs[nObsFile]); nll_putmsg(1, MsgStr); // check if observations are read from file(s) if ((n_obs_lines <= 0)) { /* open observation file */ if ((fp_obs = fopen(fn_loc_obs[nObsFile], "r")) == NULL) { nll_puterr2("ERROR: opening observations file", fn_loc_obs[nObsFile]); continue; } else { NumFilesOpen++; } /* extract info from filename */ if ((istat = ExtractFilenameInfo(fn_loc_obs[nObsFile], ftype_obs)) < 0) nll_puterr("WARNING: error extractng information from filename."); } /* read arrivals and locate event for each */ /* event (set of observations) in file */ NumArrivals = 0; while (1) { iLocated = 0; if (i_end_of_input) break; if (NumArrivals != OBS_FILE_SKIP_INPUT_LINE) { nll_putmsg(2, ""); sprintf(MsgStr, "Reading next set of observations (Files open: Tot:%d Buf:%d Hdr:%d Alloc: %d) ...", NumFilesOpen, NumGridBufFilesOpen, NumGridHdrFilesOpen, NumAllocations); nll_putmsg(1, MsgStr); } /* read next set of observations */ NumArrivalsLocation = 0; if ((NumArrivals = GetObservations(fp_obs, ftype_obs, fn_loc_grids, Arrival, &i_end_of_input, &numArrivalsIgnore, &numArrivalsReject, MaxNumArrLoc, &Hypocenter, &maxArrExceeded, &numSArrivalsLocation, 0)) == 0) break; if (NumArrivals < 0) goto cleanup; /* set number of arrivals to be used in location */ NumArrivalsLocation = NumArrivals - numArrivalsIgnore; NumArrivalsRead = NumArrivals + numArrivalsReject; nll_putmsg(2, ""); // AJL 20040720 SetOutName(Arrival + 0, fn_path_output, fn_root_out, fn_root_out_last, 1); SetOutName(Arrival + 0, fn_path_output, fn_root_out, fn_root_out_last, iSaveDecSec, &n_file_root_count); //strcpy(fn_root_out_last, fn_root_out); /* save filename */ sprintf(MsgStr, "... %d observations read, %d will be used for location (%s).", NumArrivalsRead, NumArrivalsLocation, fn_root_out); nll_putmsg(1, MsgStr); /* sort to get rejected arrivals at end of arrivals array */ if ((istat = SortArrivalsIgnore(Arrival, NumArrivalsRead)) < 0) { nll_puterr("ERROR: sorting arrivals by ignore flag."); goto cleanup; } /* check for minimum number of arrivals */ if (NumArrivalsLocation < MinNumArrLoc) { sprintf(MsgStr, "WARNING: too few observations to locate (%d available, %d needed), skipping event.", NumArrivalsLocation, MinNumArrLoc); nll_putmsg(1, MsgStr); sprintf(MsgStr, "INFO: %d observations needed (specified in control file entry LOCMETH).", MinNumArrLoc); nll_putmsg(2, MsgStr); goto cleanup; } /* check for minimum number of S arrivals */ if (numSArrivalsLocation < MinNumSArrLoc) { sprintf(MsgStr, "WARNING: too few S observations to locate (%d available, %d needed), skipping event.", numSArrivalsLocation, MinNumSArrLoc); nll_putmsg(1, MsgStr); sprintf(MsgStr, "INFO: %d S observations needed (specified in control file entry LOCMETH).", MinNumSArrLoc); nll_putmsg(2, MsgStr); goto cleanup; } /* process arrivals */ /* add stations to station list */ // station distribution weighting if (iSetStationDistributionWeights || iSaveNLLocSum || octtreeParams.use_stations_density) { //printf(">>>>>>>>>>> NumStations %d, NumArrivals %d, numArrivalsReject %d\n", NumStations, NumArrivals, numArrivalsReject); NumStations = addToStationList(StationList, NumStations, Arrival, NumArrivalsRead); if (iSetStationDistributionWeights) setStationDistributionWeights(StationList, NumStations, Arrival, NumArrivals); } /* sort to get location arrivals in time order */ if ((istat = SortArrivalsIgnore(Arrival, NumArrivals)) < 0) { nll_puterr("ERROR: sorting arrivals by ignore flag."); goto cleanup; } if ((istat = SortArrivalsTime(Arrival, NumArrivalsLocation)) < 0) { nll_puterr("ERROR: sorting arrivals by time."); goto cleanup; } /* construct weight matrix (TV82, eq. 10-9; MEN92, eq. 12) */ if ((istat = ConstWeightMatrix(NumArrivalsLocation, Arrival, &Gauss)) < 0) { nll_puterr("ERROR: constructing weight matrix - NLLoc requires non-zero observation or modelisation errors."); /* close time grid files and continue */ goto cleanup; } /* calculate weighted mean of obs arrival times */ /* (TV82, eq. A-38) */ CalcCenteredTimesObs(NumArrivalsLocation, Arrival, &Gauss, &Hypocenter); /* preform location for each grid */ sprintf(MsgStr, "Locating... (Files open: Tot:%d Buf:%d Hdr:%d Alloc: %d 3DMem: %d) ...", NumFilesOpen, NumGridBufFilesOpen, NumGridHdrFilesOpen, NumAllocations, Num3DGridReadToMemory); nll_putmsg(1, MsgStr); for (ngrid = 0; ngrid < NumLocGrids; ngrid++) { if ((istat = Locate(ngrid, fn_loc_obs[nObsFile], fn_root_out, numArrivalsReject, return_locations, return_oct_tree_grid, return_scatter_sample, ploc_list_head)) < 0) { if (istat == GRID_NOT_INSIDE) break; else { nll_puterr("ERROR: location failed."); goto cleanup; } } } NumEventsLocated++; if (istat == 0 && ngrid == NumLocGrids) NumLocationsCompleted++; iLocated = 1; cleanup: ; NumEvents++; //n_file_root_count++; /* release grid buffer or sheet storage */ // 20130413 AJL - bug? fix, release memory for all arrivals read //for (narr = 0; narr < NumArrivalsLocation; narr++) { for (narr = 0; narr < NumArrivals; narr++) { //printf("DEBUG: FREE: narr %d Arrival[narr].n_time_grid %d\n", narr, Arrival[narr].n_time_grid); if (Arrival[narr].n_time_grid < 0) { // check has opened time grid DestroyGridArray(&(Arrival[narr].sheetdesc)); FreeGrid(&(Arrival[narr].sheetdesc)); NLL_DestroyGridArray(&(Arrival[narr].gdesc)); NLL_FreeGrid(&(Arrival[narr].gdesc)); } } // 20141219 AJL - bug fix, should be outside events/obs loop! //NLL_FreeGridMemory(); /* close time grid files (opened in function GetObservations) */ // 20130413 AJL - bug? fix, release memory for all arrivals read //for (narr = 0; narr < NumArrivalsLocation; narr++) { for (narr = 0; narr < NumArrivals; narr++) { CloseGrid3dFile(&(Arrival[narr].fpgrid), &(Arrival[narr].fphdr)); } if (iLocated) { nll_putmsg(2, ""); sprintf(MsgStr, "Finished event location, output files: %s.* <%s.grid0.loc.hyp>", fn_root_out, fn_root_out); nll_putmsg(0, MsgStr); } else nll_putmsg(2, ""); // 201101013 AJL - Bug fix - this cleanup was done in NLLocLib.c->clean_memory() which puts the cleanup incorrectly inside the Locate loop CleanWeightMatrix(); } /* next event */ nll_putmsg(2, ""); sprintf(MsgStr, "...end of observation file detected."); nll_putmsg(1, MsgStr); if ((n_obs_lines <= 0)) { // observations are read from file(s) fclose(fp_obs); NumFilesOpen--; } else { // observation lines are read from memory stream (20101110 AJL) // AJL 20101110 - Bug fix for function version fclose(fp_obs); } } /* next observation file */ nll_putmsg(2, ""); sprintf(MsgStr, "No more observation files. %d events read, %d events located, %d locations completed.", NumEvents, NumEventsLocated, NumLocationsCompleted); nll_putmsg(0, MsgStr); nll_putmsg(2, ""); /* write cumulative arrival statistics */ if (!iSaveNone) { for (ngrid = 0; ngrid < NumLocGrids; ngrid++) { if (LocGridSave[ngrid]) { sprintf(fname, "%s.sum.grid%d.loc.stat", fn_path_output, ngrid); if ((fpio = fopen(fname, "w")) == NULL) { nll_puterr2( "ERROR: opening cumulative phase statistics output file", fname); return_value = EXIT_ERROR_FILEIO; goto cleanup_return; } else { NumFilesOpen++; } WriteStaStatTable(ngrid, fpio, RMS_Max, NRdgs_Min, Gap_Max, P_ResidualMax, S_ResidualMax, Ell_Len3_Max, Hypo_Depth_Min, Hypo_Depth_Max, Hypo_Dist_Max, WRITE_RESIDUALS); WriteStaStatTable(ngrid, fpio, RMS_Max, NRdgs_Min, Gap_Max, P_ResidualMax, S_ResidualMax, Ell_Len3_Max, Hypo_Depth_Min, Hypo_Depth_Max, Hypo_Dist_Max, WRITE_RES_DELAYS); WriteStaStatTable(ngrid, fpio, RMS_Max, NRdgs_Min, Gap_Max, P_ResidualMax, S_ResidualMax, Ell_Len3_Max, Hypo_Depth_Min, Hypo_Depth_Max, Hypo_Dist_Max, WRITE_PDF_RESIDUALS); WriteStaStatTable(ngrid, fpio, RMS_Max, NRdgs_Min, Gap_Max, P_ResidualMax, S_ResidualMax, Ell_Len3_Max, Hypo_Depth_Min, Hypo_Depth_Max, Hypo_Dist_Max, WRITE_PDF_DELAYS); fclose(fpio); // save to last sprintf(sys_command, "cp %s %slast.stat", fname, f_outpath); system(sys_command); // write delays only sprintf(fname, "%s.sum.grid%d.loc.stat_totcorr", fn_path_output, ngrid); if ((fpio = fopen(fname, "w")) == NULL) { nll_puterr2( "ERROR: opening total phase corrections output file", fname); return_value = EXIT_ERROR_FILEIO; goto cleanup_return; } else { NumFilesOpen++; } WriteStaStatTable(ngrid, fpio, RMS_Max, NRdgs_Min, Gap_Max, P_ResidualMax, S_ResidualMax, Ell_Len3_Max, Hypo_Depth_Min, Hypo_Depth_Max, Hypo_Dist_Max, WRITE_RES_DELAYS); fclose(fpio); // save to last sprintf(sys_command, "cp %s %slast.stat_totcorr", fname, f_outpath); system(sys_command); } } } /* write station list */ if (!iSaveNone) { for (ngrid = 0; ngrid < NumLocGrids; ngrid++) if (LocGridSave[ngrid]) { sprintf(fname, "%s.sum.grid%d.loc.stations", fn_path_output, ngrid); if ((fpio = fopen(fname, "w")) == NULL) { nll_puterr2( "ERROR: opening cumulative phase statistics output file", fname); return_value = EXIT_ERROR_FILEIO; goto cleanup_return; } else { NumFilesOpen++; } WriteStationList(fpio, StationList, NumStations); fclose(fpio); // save to last sprintf(sys_command, "cp %s %slast.stations", fname, f_outpath); system(sys_command); } } // clean up before leaving NLLoc function cleanup_return: // 20141219 AJL - bug? fix, moved here from inside events/obs loop! NLL_FreeGridMemory(); if (!iSaveNone) CloseSummaryFiles(); if (fp_model_grid_P != NULL) { CloseGrid3dFile(&fp_model_grid_P, &fp_model_hdr_P); } if (fp_model_grid_S != NULL) { CloseGrid3dFile(&fp_model_grid_S, &fp_model_hdr_S); } // AEH/AJL 20080709 if (Arrival != NULL) { free(Arrival); Arrival = NULL; } // AJL 20101110 - Bug fix for function version for (ngrid = 0; ngrid < NumLocGrids; ngrid++) { // 20100607 AJL added to prevent valgrind error of not-freed blocks FreeStaStatTable(ngrid); } // AJL 20100929 - Bug fix for function version // free any allocated surface data if (topo_surface_index >= 0) { free_surface(topo_surface); } for (n = 0; n < NumTimeDelaySurface; n++) { free_surface(model_surface + n); } if (bp_memory_stream != NULL) { free(bp_memory_stream); bp_memory_stream = NULL; } return (return_value); }