int main (int argc, char * argv[]) { // Plant frequencies... (zeroed here just to suppress a -Wall warning) float f_AA_MM = 0; float f_AA_Mm = 0; float f_AA_mm = 0; float f_Aa_MM = 0; float f_Aa_Mm = 0; float f_Aa_mm = 0; float f_aa_MM = 0; float f_aa_Mm = 0; float f_aa_mm = 0; float next_f_AA_MM; float next_f_AA_Mm; float next_f_AA_mm; float next_f_Aa_MM; float next_f_Aa_Mm; float next_f_Aa_mm; float next_f_aa_MM; float next_f_aa_Mm; float next_f_aa_mm; // Pollen frequencies... float p_A_M; float p_A_m; float p_a_M; float p_a_m; // Egg frequencies... float e_A_M; float e_A_m; float e_a_M; float e_a_m; float male = 0; float female = 0; float inconstant = 0; float PSatC; // Pollen saturation point for cosex receivers float K; float k; float totalpollen; float totalplants; int n; int x; int y; char bmp_filename[1024]; char txt_filename[1024]; FILE * textfile = NULL; parsecommandline(argc, argv); result = malloc(subdivisions * sizeof(int*)); if (result == NULL) { printf("Out of memory!\n"); exit(1); } for (n = 0; n < subdivisions; n++) { result[n] = malloc(subdivisions * sizeof(int)); if (result[n] == NULL) { printf("Out of memory!\n"); exit(1); } } // Print all settings... printf("\nModel %d\n\n", MODEL); if (onerun) { printf("Q = %G (K = %G, pi = %G)\n", Q, (1 / Q) - 1, 1 / Q); printf("F = %G (k = %G, \"omega\" = %G)\n\n", F, (1 / F) - 1, 1 / F); } printf("h = %G\n", h); printf("Selfing rate = %G\n", S); printf("Inbreeding depression = %G\n", d); printf("YY viability = %G (YY penalty = %G)\n", V, 1 - V); printf("PSatF = %G\n\n", PSatF); printf("Iterations = %d\n\n", endpoint); if (onerun == 0) { printf("Warning: --onerun option not received, therefore program will\n"); printf("use %d Q and F combinations and produce a graph. This may\n", subdivisions * subdivisions); printf("take a long time. If this was not your intention, terminate now.\n\n"); printf(" %d |\n", oldformat ? oldformatlimit : 1); printf("Output format: %s |\n", oldformat ? "k" : "F"); printf(" 0 |\n"); printf(" -----\n"); printf(" 0 %d\n", oldformat ? oldformatlimit : 1); printf(" %s\n\n", oldformat ? "K" : "Q"); } // Choose names for .bmp and .txt output files (if needed)... sprintf(bmp_filename, "model%d_start%s_V%G_S%G_d%G_h%G_PSatF%G_ppY%G.bmp", MODEL, pgd ? "PGD" : "DIO", V, S, d, h, PSatF, ppY); sprintf(txt_filename, "model%d_start%s_V%G_S%G_d%G_h%G_PSatF%G_ppY%G.txt", MODEL, pgd ? "PGD" : "DIO", V, S, d, h, PSatF, ppY); // Open .txt output file (if needed)... if (onerun == 0 && gnuplot) { textfile = fopen(txt_filename, "w"); } for (y = 0; y < subdivisions; y++) { for (x = 0; x < subdivisions; x++) { if (onerun == 0) { // Here we map the X,Y coordinates of our output .bmp file onto Q and F parameters... if (oldformat == 0) { Q = (float) x / (subdivisions - 1); // X axis: Q values 0 to 1 F = (float) y / (subdivisions - 1); // Y axis: F values 0 to 1 } else { K = ((float) x / (subdivisions - 1)) * oldformatlimit; // X axis: K values 0 to oldformatlimit k = ((float) y / (subdivisions - 1)) * oldformatlimit; // Y axis: k values 0 to oldformatlimit // But Q and F are the parameters actually used by the code, so calculate them: Q = 1 / (1 + K); F = 1 / (1 + k); } } // Set start plant frequencies... if (pgd == 0) // Start with DIOECY, try inconstant invasion { f_AA_MM = 0; f_AA_Mm = 0; f_AA_mm = 0.499; f_Aa_MM = 0; f_Aa_Mm = 0.002; f_Aa_mm = 0.499; f_aa_MM = 0; f_aa_Mm = 0; f_aa_mm = 0; } else { // Start with PSEUDO-GYNODIOECY, try male invasion f_AA_MM = 0.499; f_AA_Mm = 0; f_AA_mm = 0; f_Aa_MM = 0.499; f_Aa_Mm = 0; f_Aa_mm = 0.002; f_aa_MM = 0; f_aa_Mm = 0; f_aa_mm = 0; } for (n = 0; n < endpoint; n++) { // Outcrossed pollen frequencies.................................................... // // Here we sum up the 4 types of pollen (containing the 4 possible allele combinations) // from the various possible sources. We could do this in 4 equations (as in the paper) // but it's simpler to consider each source in turn and add to the totals. p_A_M = 0; p_A_m = 0; p_a_M = 0; p_a_m = 0; // From AA MM pure females (genotype 1) ; // From AA Mm pure females (genotype 2) ; // From AA mm pure females (genotype 3) ; // From Aa MM inconstants (genotype 4) as cosexes p_A_M += f_Aa_MM * 0.5 * h * Q; p_a_M += f_Aa_MM * 0.5 * h * Q; // From Aa MM inconstants (genotype 4) as males p_A_M += f_Aa_MM * 0.5 * (1 - h); p_a_M += f_Aa_MM * 0.5 * (1 - h); // From Aa Mm inconstants (genotype 5) as cosexes p_A_M += f_Aa_Mm * 0.25 * h * Q; p_A_m += f_Aa_Mm * 0.25 * h * Q; p_a_M += f_Aa_Mm * 0.25 * h * Q; p_a_m += f_Aa_Mm * 0.25 * h * Q; // From Aa Mm inconstants (genotype 5) as males p_A_M += f_Aa_Mm * 0.25 * (1 - h); p_A_m += f_Aa_Mm * 0.25 * (1 - h); p_a_M += f_Aa_Mm * 0.25 * (1 - h); p_a_m += f_Aa_Mm * 0.25 * (1 - h); // From Aa mm pure males (genotype 6) p_A_m += f_Aa_mm * 0.5; p_a_m += f_Aa_mm * 0.5; // From aa MM inconstants (genotype 7) as cosexes p_a_M += f_aa_MM * h * Q; // From aa MM inconstants (genotype 7) as males p_a_M += f_aa_MM * (1 - h); // From aa Mm inconstants (genotype 8) as cosexes p_a_M += f_aa_Mm * 0.5 * h * Q; p_a_m += f_aa_Mm * 0.5 * h * Q; // From aa Mm inconstants (genotype 8) as males p_a_M += f_aa_Mm * 0.5 * (1 - h); p_a_m += f_aa_Mm * 0.5 * (1 - h); // From aa mm pure males (genotype 9) p_a_m += f_aa_mm; // Normalise pollen frequencies to add up to 1...................................... totalpollen = p_A_M + p_A_m + p_a_M + p_a_m; if (totalpollen > 0) { p_A_M /= totalpollen; p_A_m /= totalpollen; p_a_M /= totalpollen; p_a_m /= totalpollen; } // Outcrossed egg frequencies....................................................... // Calculate pollen required to fertilise a cosex's outcrossing ovules: PSatC = PSatF * F * (1 - S); e_A_M = 0; e_A_m = 0; e_a_M = 0; e_a_m = 0; // From AA MM pure females (genotype 1) if (totalpollen >= PSatF) { e_A_M += f_AA_MM; } else { e_A_M += f_AA_MM * totalpollen / PSatF; } // From AA Mm pure females (genotype 2) if (totalpollen >= PSatF) { e_A_M += f_AA_Mm * 0.5; e_A_m += f_AA_Mm * 0.5; } else { e_A_M += f_AA_Mm * 0.5 * totalpollen / PSatF; e_A_m += f_AA_Mm * 0.5 * totalpollen / PSatF; } // From AA mm pure females (genotype 3) if (totalpollen >= PSatF) { e_A_m += f_AA_mm; } else { e_A_m += f_AA_mm * totalpollen / PSatF; } // From Aa MM inconstants (genotype 4) as cosexes if (totalpollen >= PSatC) { e_A_M += f_Aa_MM * h * 0.5 * (1 - S) * F; e_a_M += f_Aa_MM * h * 0.5 * (1 - S) * F; } else { e_A_M += f_Aa_MM * h * 0.5 * (1 - S) * F * totalpollen / PSatC; e_a_M += f_Aa_MM * h * 0.5 * (1 - S) * F * totalpollen / PSatC; } // From Aa Mm inconstants (genotype 5) as cosexes if (totalpollen >= PSatC) { e_A_M += f_Aa_Mm * h * 0.25 * (1 - S) * F; e_A_m += f_Aa_Mm * h * 0.25 * (1 - S) * F; e_a_M += f_Aa_Mm * h * 0.25 * (1 - S) * F; e_a_m += f_Aa_Mm * h * 0.25 * (1 - S) * F; } else { e_A_M += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC; e_A_m += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC; e_a_M += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC; e_a_m += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC; } // From Aa mm pure males (genotype 6) ; // From aa MM inconstants (genotype 7) as cosexes if (totalpollen >= PSatC) { e_a_M += f_aa_MM * h * (1 - S) * F; } else { e_a_M += f_aa_MM * h * (1 - S) * F * totalpollen / PSatC; } // From aa Mm inconstants (genotype 8) as cosexes if (totalpollen >= PSatC) { e_a_M += f_aa_Mm * h * 0.5 * (1 - S) * F; e_a_m += f_aa_Mm * h * 0.5 * (1 - S) * F; } else { e_a_M += f_aa_Mm * h * 0.5 * (1 - S) * F * totalpollen / PSatC; e_a_m += f_aa_Mm * h * 0.5 * (1 - S) * F * totalpollen / PSatC; } // From aa mm pure males (genotype 9) ; // WE CANNOT AND MUST NOT NORMALISE THE EGG FREQUENCIES, AS WE HAVEN'T // YET CONSIDERED THE SELFED EGGS. BUT WE DON'T NEED TO NORMALISE. // Plant frequencies from outcrossing............................................... next_f_AA_MM = p_A_M * e_A_M; next_f_AA_Mm = p_A_M * e_A_m + p_A_m * e_A_M; next_f_AA_mm = p_A_m * e_A_m; next_f_Aa_MM = p_A_M * e_a_M + p_a_M * e_A_M; next_f_Aa_Mm = p_A_M * e_a_m + p_A_m * e_a_M + p_a_M * e_A_m + p_a_m * e_A_M; next_f_Aa_mm = p_A_m * e_a_m + p_a_m * e_A_m; next_f_aa_MM = p_a_M * e_a_M; next_f_aa_Mm = p_a_M * e_a_m + p_a_m * e_a_M; next_f_aa_mm = p_a_m * e_a_m; // Additional plants from selfing................................................... // From AA MM pure females (genotype 1) ; // From AA Mm pure females (genotype 2) ; // From AA mm pure females (genotype 3) ; // From Aa MM inconstants (genotype 4) next_f_AA_MM += f_Aa_MM * 0.25 * S * (1 - d) * h * F; next_f_Aa_MM += f_Aa_MM * 0.5 * S * (1 - d) * h * F; next_f_aa_MM += f_Aa_MM * 0.25 * S * (1 - d) * h * F; // From Aa Mm inconstants (genotype 5) next_f_AA_MM += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F; next_f_AA_Mm += f_Aa_Mm * 0.125 * S * (1 - d) * h * F; next_f_AA_mm += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F; next_f_Aa_MM += f_Aa_Mm * 0.125 * S * (1 - d) * h * F; next_f_Aa_Mm += f_Aa_Mm * 0.25 * S * (1 - d) * h * F; next_f_Aa_mm += f_Aa_Mm * 0.125 * S * (1 - d) * h * F; next_f_aa_MM += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F; next_f_aa_Mm += f_Aa_Mm * 0.125 * S * (1 - d) * h * F; next_f_aa_mm += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F; // From Aa mm pure males (genotype 6) ; // From aa MM inconstants (genotype 7) next_f_aa_MM += f_aa_MM * S * (1 - d) * h * F; // From aa Mm inconstants (genotype 8) next_f_aa_MM += f_aa_Mm * 0.25 * S * (1 - d) * h * F; next_f_aa_Mm += f_aa_Mm * 0.5 * S * (1 - d) * h * F; next_f_aa_mm += f_aa_Mm * 0.25 * S * (1 - d) * h * F; // From aa mm pure males (genotype 9) ; // Apply YY penalty................................................................. next_f_aa_MM *= V; next_f_aa_Mm *= V; next_f_aa_mm *= V; // Copy............................................................................. f_AA_MM = next_f_AA_MM; f_AA_Mm = next_f_AA_Mm; f_AA_mm = next_f_AA_mm; f_Aa_MM = next_f_Aa_MM; f_Aa_Mm = next_f_Aa_Mm; f_Aa_mm = next_f_Aa_mm; f_aa_MM = next_f_aa_MM; f_aa_Mm = next_f_aa_Mm; f_aa_mm = next_f_aa_mm; // Normalise plant frequencies to add up to 1....................................... totalplants = f_AA_MM + f_AA_Mm + f_AA_mm + f_Aa_MM + f_Aa_Mm + f_Aa_mm + f_aa_MM + f_aa_Mm + f_aa_mm; if (totalplants > 0) { f_AA_MM /= totalplants; f_AA_Mm /= totalplants; f_AA_mm /= totalplants; f_Aa_MM /= totalplants; f_Aa_Mm /= totalplants; f_Aa_mm /= totalplants; f_aa_MM /= totalplants; f_aa_Mm /= totalplants; f_aa_mm /= totalplants; } } // Calculate and save results... female = f_AA_MM + f_AA_Mm + f_AA_mm; male = f_Aa_mm + f_aa_mm; inconstant = f_Aa_MM + f_Aa_Mm + f_aa_MM + f_aa_Mm; if (male > threshold && female > threshold && inconstant > threshold) { result[x][y] = SSD; } else if (male > threshold && female > threshold) { result[x][y] = DIO; } else if (female > threshold && inconstant > threshold) { result[x][y] = PGD; } else if (male > threshold && inconstant > threshold) { result[x][y] = PAD; } else if (inconstant > threshold) { result[x][y] = INC; } else { result[x][y] = 0; } if (onerun == 0 && gnuplot) { fprintf(textfile, "%f", female); if (x == subdivisions - 1) { fprintf(textfile, "\n"); } else { fprintf(textfile, "\t"); } } if (onerun) break; } if (onerun) break; } if (onerun == 0) { drawbmp(bmp_filename, 1); printf("Saved %s\n", bmp_filename); } else { printf("Females Males Inconstants\n"); printf("%.6f %.6f %.6f\n\n", female, male, inconstant); printf("Genotype frequencies, as notated by E&B (2007), or C&C (2012):\n\n"); printf("E&B: AA MM AA Mm AA mm Aa MM Aa Mm Aa mm aa MM aa Mm aa mm\n"); printf("C&C: mm AA mm Aa mm aa Mm AA Mm Aa Mm aa MM AA MM Aa MM aa\n"); printf(" %.6f %.6f %.6f %.6f %.6f %.6f %.6f %.6f %.6f\n\n", f_AA_MM, f_AA_Mm, f_AA_mm, f_Aa_MM, f_Aa_Mm, f_Aa_mm, f_aa_MM, f_aa_Mm, f_aa_mm); if (male > threshold && female > threshold && inconstant > threshold) { printf("Final state: SSD\n"); } else if (male > threshold && female > threshold) { printf("Final state: DIO\n"); } else if (female > threshold && inconstant > threshold) { printf("Final state: PGD\n"); } else if (male > threshold && inconstant > threshold) { printf("Final state: PAD\n"); } else if (inconstant > threshold) { printf("Final state: INC\n"); } else { printf("Final state: ???\n"); } } return 0; }
static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) { fz_page *page; fz_display_list *list = NULL; fz_device *dev = NULL; int start; fz_cookie cookie = { 0 }; int needshot = 0; fz_var(list); fz_var(dev); if (showtime) { start = gettime(); } fz_try(ctx) { page = fz_load_page(doc, pagenum - 1); } fz_catch(ctx) { fz_throw(ctx, "cannot load page %d in file '%s'", pagenum, filename); } if (mujstest_file) { fz_interactive *inter = fz_interact(doc); fz_widget *widget = NULL; if (inter) widget = fz_first_widget(inter, page); if (widget) { fprintf(mujstest_file, "GOTO %d\n", pagenum); needshot = 1; } for (;widget; widget = fz_next_widget(inter, widget)) { fz_rect rect = fz_widget_bbox(widget); int w = (rect.x1-rect.x0); int h = (rect.y1-rect.y0); int len; int type = fz_widget_get_type(widget); ++mujstest_count; switch (type) { default: fprintf(mujstest_file, "%% UNKNOWN %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); break; case FZ_WIDGET_TYPE_PUSHBUTTON: fprintf(mujstest_file, "%% PUSHBUTTON %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); break; case FZ_WIDGET_TYPE_CHECKBOX: fprintf(mujstest_file, "%% CHECKBOX %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); break; case FZ_WIDGET_TYPE_RADIOBUTTON: fprintf(mujstest_file, "%% RADIOBUTTON %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); break; case FZ_WIDGET_TYPE_TEXT: { int maxlen = fz_text_widget_max_len(inter, widget); int texttype = fz_text_widget_content_type(inter, widget); /* If height is low, assume a single row, and base * the width off that. */ if (h < 10) { w = (w+h-1) / (h ? h : 1); h = 1; } /* Otherwise, if width is low, work off height */ else if (w < 10) { h = (w+h-1) / (w ? w : 1); w = 1; } else { w = (w+9)/10; h = (h+9)/10; } len = w*h; if (len < 2) len = 2; if (len > maxlen) len = maxlen; fprintf(mujstest_file, "%% TEXT %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); switch (texttype) { default: case FZ_WIDGET_CONTENT_UNRESTRAINED: fprintf(mujstest_file, "TEXT %d ", mujstest_count); escape_string(mujstest_file, len-3, lorem); fprintf(mujstest_file, "\n"); break; case FZ_WIDGET_CONTENT_NUMBER: fprintf(mujstest_file, "TEXT %d\n", mujstest_count); break; case FZ_WIDGET_CONTENT_SPECIAL: fprintf(mujstest_file, "TEXT %lld\n", 46702919800LL + mujstest_count); break; case FZ_WIDGET_CONTENT_DATE: fprintf(mujstest_file, "TEXT Jun %d 1979\n", 1 + ((13 + mujstest_count) % 30)); break; case FZ_WIDGET_CONTENT_TIME: ++mujstest_count; fprintf(mujstest_file, "TEXT %02d:%02d\n", ((mujstest_count/60) % 24), mujstest_count % 60); break; } break; } case FZ_WIDGET_TYPE_LISTBOX: fprintf(mujstest_file, "%% LISTBOX %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); break; case FZ_WIDGET_TYPE_COMBOBOX: fprintf(mujstest_file, "%% COMBOBOX %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1); break; } fprintf(mujstest_file, "CLICK %0.2f %0.2f\n", (rect.x0+rect.x1)/2, (rect.y0+rect.y1)/2); } } if (uselist) { fz_try(ctx) { list = fz_new_display_list(ctx); dev = fz_new_list_device(ctx, list); fz_run_page(doc, page, dev, fz_identity, &cookie); } fz_always(ctx) { fz_free_device(dev); dev = NULL; } fz_catch(ctx) { fz_free_display_list(ctx, list); fz_free_page(doc, page); fz_throw(ctx, "cannot draw page %d in file '%s'", pagenum, filename); } } if (showxml) { fz_try(ctx) { dev = fz_new_trace_device(ctx); fz_printf(out, "<page number=\"%d\">\n", pagenum); if (list) fz_run_display_list(list, dev, fz_identity, fz_infinite_rect, &cookie); else fz_run_page(doc, page, dev, fz_identity, &cookie); fz_printf(out, "</page>\n"); } fz_always(ctx) { fz_free_device(dev); dev = NULL; } fz_catch(ctx) { fz_free_display_list(ctx, list); fz_free_page(doc, page); fz_rethrow(ctx); } } if (showtext) { fz_text_page *text = NULL; fz_var(text); fz_try(ctx) { text = fz_new_text_page(ctx, fz_bound_page(doc, page)); dev = fz_new_text_device(ctx, sheet, text); if (list) fz_run_display_list(list, dev, fz_identity, fz_infinite_rect, &cookie); else fz_run_page(doc, page, dev, fz_identity, &cookie); fz_free_device(dev); dev = NULL; if (showtext == TEXT_XML) { fz_print_text_page_xml(ctx, out, text); } else if (showtext == TEXT_HTML) { fz_print_text_page_html(ctx, out, text); } else if (showtext == TEXT_PLAIN) { fz_print_text_page(ctx, out, text); fz_printf(out, "\f\n"); } } fz_always(ctx) { fz_free_device(dev); dev = NULL; fz_free_text_page(ctx, text); } fz_catch(ctx) { fz_free_display_list(ctx, list); fz_free_page(doc, page); fz_rethrow(ctx); } } if (showmd5 || showtime) printf("page %s %d", filename, pagenum); #ifdef GDI_PLUS_BMP_RENDERER // hack: use -G0 to "enable GDI+" when saving as TGA if (output && (strstr(output, ".bmp") || strstr(output, ".tga") && !gamma_value)) drawbmp(ctx, doc, page, list, pagenum); else #endif if (output || showmd5 || showtime) { float zoom; fz_matrix ctm; fz_rect bounds, tbounds; fz_bbox ibounds; fz_pixmap *pix = NULL; int w, h; fz_var(pix); bounds = fz_bound_page(doc, page); zoom = resolution / 72; ctm = fz_scale(zoom, zoom); ctm = fz_concat(ctm, fz_rotate(rotation)); tbounds = fz_transform_rect(ctm, bounds); ibounds = fz_round_rect(tbounds); /* convert to integers */ /* Make local copies of our width/height */ w = width; h = height; /* If a resolution is specified, check to see whether w/h are * exceeded; if not, unset them. */ if (res_specified) { int t; t = ibounds.x1 - ibounds.x0; if (w && t <= w) w = 0; t = ibounds.y1 - ibounds.y0; if (h && t <= h) h = 0; } /* Now w or h will be 0 unless they need to be enforced. */ if (w || h) { float scalex = w / (tbounds.x1 - tbounds.x0); float scaley = h / (tbounds.y1 - tbounds.y0); if (fit) { if (w == 0) scalex = 1.0f; if (h == 0) scaley = 1.0f; } else { if (w == 0) scalex = scaley; if (h == 0) scaley = scalex; } if (!fit) { if (scalex > scaley) scalex = scaley; else scaley = scalex; } ctm = fz_concat(ctm, fz_scale(scalex, scaley)); tbounds = fz_transform_rect(ctm, bounds); } ibounds = fz_round_rect(tbounds); /* TODO: banded rendering and multi-page ppm */ fz_try(ctx) { pix = fz_new_pixmap_with_bbox(ctx, colorspace, ibounds); if (savealpha) fz_clear_pixmap(ctx, pix); else fz_clear_pixmap_with_value(ctx, pix, 255); dev = fz_new_draw_device(ctx, pix); if (list) fz_run_display_list(list, dev, ctm, tbounds, &cookie); else fz_run_page(doc, page, dev, ctm, &cookie); fz_free_device(dev); dev = NULL; if (invert) fz_invert_pixmap(ctx, pix); if (gamma_value != 1) fz_gamma_pixmap(ctx, pix, gamma_value); if (savealpha) fz_unmultiply_pixmap(ctx, pix); if (output) { char buf[512]; sprintf(buf, output, pagenum); if (strstr(output, ".pgm") || strstr(output, ".ppm") || strstr(output, ".pnm")) fz_write_pnm(ctx, pix, buf); else if (strstr(output, ".pam")) fz_write_pam(ctx, pix, buf, savealpha); else if (strstr(output, ".png")) fz_write_png(ctx, pix, buf, savealpha); else if (strstr(output, ".pbm")) { fz_bitmap *bit = fz_halftone_pixmap(ctx, pix, NULL); fz_write_pbm(ctx, bit, buf); fz_drop_bitmap(ctx, bit); } /* SumatraPDF: support TGA as output format */ else if (strstr(output, ".tga")) fz_write_tga(ctx, pix, buf, savealpha); } if (showmd5) { unsigned char digest[16]; int i; fz_md5_pixmap(pix, digest); printf(" "); for (i = 0; i < 16; i++) printf("%02x", digest[i]); } } fz_always(ctx) { fz_free_device(dev); dev = NULL; fz_drop_pixmap(ctx, pix); } fz_catch(ctx) { fz_free_display_list(ctx, list); fz_free_page(doc, page); fz_rethrow(ctx); } }
int main (int argc, char * argv[]) { int i, j, n; // General purpose counters double x, y; // Source coordinates of particle being tracked int source_column, source_row; // Source grid location double r, s, nextr, nexts; // Values as particle is iterated through the Mandelbrot function double x_jump, y_jump; // Distances between particles in the source grid double target_startx, target_starty; // Top-left coordinates of drawn area double target_endx, target_endy; // Bottom-right coordinates of drawn area double pixel_width; // Actual distance represented by a pixel in the drawn area char filename[200]; for (i = 0; i < WIDTH; i++) { for (j = 0; j < HEIGHT; j++) { redcount[i][j] = 0; greencount[i][j] = 0; bluecount[i][j] = 0; } } /* target_startx = CENTRE_X - ((double) WIDTH / (ZOOM * 2)); target_endx = CENTRE_X + ((double) WIDTH / (ZOOM * 2)); target_starty = CENTRE_Y - ((double) HEIGHT / (ZOOM * 2)); target_endy = CENTRE_Y + ((double) HEIGHT / (ZOOM * 2)); pixel_width = (target_endx - target_startx) / WIDTH; x_jump = ((double) SOURCE_RIGHT_X - SOURCE_LEFT_X) / SOURCE_COLUMNS; y_jump = ((double) SOURCE_BOTTOM_Y - SOURCE_TOP_Y) / SOURCE_ROWS; */ // Map Source (world space) to Pixels (image space) double world_2_image_x = (double)(WIDTH -1) / ((double) SOURCE_RIGHT_X - SOURCE_LEFT_X); double world_2_image_y = (double)(HEIGHT-1) / ((double) SOURCE_BOTTOM_Y - SOURCE_TOP_Y); x_jump = ((double) SOURCE_RIGHT_X - SOURCE_LEFT_X) / (SOURCE_COLUMNS - 1); y_jump = ((double) SOURCE_BOTTOM_Y - SOURCE_TOP_Y) / (SOURCE_ROWS - 1); iterations = RED_ITERATIONS_UPPER; if (GREEN_ITERATIONS_UPPER > iterations) iterations = GREEN_ITERATIONS_UPPER; if (BLUE_ITERATIONS_UPPER > iterations) iterations = BLUE_ITERATIONS_UPPER; // Main bit... //x = SOURCE_LEFT_X; //for (source_column = 0; source_column < SOURCE_COLUMNS; source_column++, x += x_jump) //{ // y = SOURCE_TOP_Y; // for (source_row = 0; source_row < SOURCE_ROWS; source_row++, y += y_jump) double x0; source_column = 0; for( x0 = SOURCE_LEFT_X; x0 < SOURCE_RIGHT_X; source_column++, x0 += x_jump ) { double y0; for( y0 = SOURCE_TOP_Y; y0 < SOURCE_BOTTOM_Y; y0 += y_jump ) { #ifdef OPTIMISE if ( (x > -1.2 && x <= -1.1 && y > -0.1 && y < 0.1) || (x > -1.1 && x <= -0.9 && y > -0.2 && y < 0.2) || (x > -0.9 && x <= -0.8 && y > -0.1 && y < 0.1) || (x > -0.69 && x <= -0.61 && y > -0.2 && y < 0.2) || (x > -0.61 && x <= -0.5 && y > -0.37 && y < 0.37) || (x > -0.5 && x <= -0.39 && y > -0.48 && y < 0.48) || (x > -0.39 && x <= 0.14 && y > -0.55 && y < 0.55) || (x > 0.14 && x < 0.29 && y > -0.42 && y < -0.07) || (x > 0.14 && x < 0.29 && y > 0.07 && y < 0.42) ) continue; #endif r = 0; s = 0; for (n = 0; n <= iterations; n++) { nextr = ((r * r) - (s * s)) + x; nexts = (2 * r * s) + y; r = nextr; s = nexts; if (n == iterations) { // drawpath(x, y, target_startx, target_starty, pixel_width); break; } else if ((r * r) + (s * s) > 4) { //drawpath(x, y, target_startx, target_starty, pixel_width); drawpath(x, y, world_2_image_x, world_2_image_y); break; } } } if (source_column % UPDATETICK == 0) { printf("Reached source column: %d of %d\n", source_column, SOURCE_COLUMNS); } } sprintf(filename, "%s r %d g %d b %d spp %d.bmp", OUTFILE, RED_ITERATIONS_UPPER, GREEN_ITERATIONS_UPPER, BLUE_ITERATIONS_UPPER, (SOURCE_COLUMNS / WIDTH) * (SOURCE_ROWS / HEIGHT)); drawbmp(filename); printf("Done.\n"); return 0; }