void write_tree (const wfa_t *wfa, bitfile_t *output) /* * Write bintree to stream 'output'. * Traverse tree in breadth first order and save a '1' for each child * and a '0' for each range image. * * No return value. */ { unsigned queue [MAXSTATES]; /* state numbers in BFO */ unsigned current; /* current node to process */ unsigned last; /* last node (update every new node) */ unsigned label; /* current label */ int into; /* next child */ byte_t *tree_string; /* bitstring to encode */ unsigned total = 0; /* number of ranges */ unsigned bits = bits_processed (output); /* number of bits */ /* * Traverse tree in breadth first order. Use a queue to store * the childs of each node ('last' is the next free queue element). * The first element ('current') of this queue will get the new parent * node. */ tree_string = Calloc (MAXSTATES * MAXLABELS, sizeof (byte_t)); queue [0] = wfa->root_state; for (last = 1, current = 0; current < last; current++) for (label = 0; label < MAXLABELS; label++) if (!isrange (into = wfa->tree [queue[current]][label])) /* child ? */ { queue [last++] = into; tree_string [total++] = 1; } else /* or range ? */ tree_string [total++] = 0; if (total != (wfa->states - wfa->basis_states) * MAXLABELS) error ("total [%d] != (states - basis_states) * 2 [%d]", total, (wfa->states - wfa->basis_states) * MAXLABELS); { unsigned scale = total / 20 ; encode_tree (output, tree_string, total, scale, 1, 11); } Free (tree_string); debug_message ("tree: %5d bits. (%5d symbols => %5.2f bps)", bits_processed (output) - bits, total, total > 0 ? ((bits_processed (output) - bits) / (double) total) : 0); }
bool Parserange_simple (char **div, bool *revcomp, Genomicpos_T *chrstart, Genomicpos_T *chrend, char *query) { char *coords; Genomicpos_T result, left, length; *revcomp = false; if (index(query,':')) { /* Segment must be a genome, chromosome, or contig */ debug(printf("Parsed query %s into ",query)); *div = strtok(query,":"); if ((*div)[0] == '+') { *revcomp = false; *div = &((*div)[1]); } else if ((*div)[0] == '_') { *revcomp = true; *div = &((*div)[1]); } coords = strtok(NULL,":"); debug(printf("segment %s and coords %s\n",*div,coords)); debug(printf("Interpreting segment %s as a chromosome\n",*div)); if (coords == NULL) { fprintf(stderr,"Need region after ':'\n"); return false; } else if (isnumberp(&result,coords)) { debug(printf(" and coords %s as a number\n",coords)); left = result - 1; /* Make 0-based */ length = 1; } else if (isrange(&left,&length,&(*revcomp),coords)) { debug(printf(" and coords %s as a range starting at %u with length %u and revcomp = %d\n", coords,left,length,*revcomp)); } else { fprintf(stderr,"Coordinates after ':' is neither a number nor a range\n"); debug(printf(" but coords %s is neither a number nor a range\n",coords)); return false; } /* Compute chromosomal coordinates */ *chrstart = left; *chrend = *chrstart + length; *chrstart += 1U; /* Make 1-based */ return true; } else { fprintf(stderr,"Region %s does not contain ':'\n",query); return false; } }
int main(int argc, char **argv) { fz_document *doc = NULL; int c; fz_context *ctx; fz_var(doc); yctx = yutani_init(); char * _width = getenv("WIDTH"); char * _height = getenv("HEIGHT"); width = _width ? atoi(_width) : 512; height = _height ? atoi(_height) : 512; init_decorations(); window = yutani_window_create(yctx, width + decor_width(), height + decor_height()); yutani_window_move(yctx, window, 50, 50); yutani_window_advertise_icon(yctx, window, "PDF Viewer", "pdfviewer"); gfx_ctx = init_graphics_yutani(window); draw_fill(gfx_ctx,rgb(0,0,0)); render_decorations(window, gfx_ctx, "PDFViewer - Loading..."); while ((c = fz_getopt(argc, argv, "wf")) != -1) { switch (c) { case 'f': fit = 1; break; } } ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT); if (!ctx) { fprintf(stderr, "Could not initialize fitz context.\n"); exit(1); } fz_set_aa_level(ctx, alphabits); colorspace = fz_device_rgb; fz_try(ctx) { while (fz_optind < argc) { fz_try(ctx) { filename = argv[fz_optind++]; files++; fz_try(ctx) { doc = fz_open_document(ctx, filename); } fz_catch(ctx) { fz_throw(ctx, "cannot open document: %s", filename); } if (fz_optind == argc || !isrange(argv[fz_optind])) drawrange(ctx, doc, "1-"); if (fz_optind < argc && isrange(argv[fz_optind])) drawrange(ctx, doc, argv[fz_optind++]); fz_close_document(doc); doc = NULL; } fz_catch(ctx) { if (!ignore_errors) fz_rethrow(ctx); fz_close_document(doc); doc = NULL; fz_warn(ctx, "ignoring error in '%s'", filename); } } } fz_catch(ctx) { fz_close_document(doc); fprintf(stderr, "error: cannot draw '%s'\n", filename); errored = 1; } fz_free_context(ctx); return (errored != 0); }
Local int compare_page(FIELD_PTR *a, FIELD_PTR *b) { int m = 0; short i = 0; while((i < (*a)->count) && (i < (*b)->count) && ((m = (*a)->npg[i] - (*b)->npg[i]) == 0)) { i++; } if(m == 0) { /* common leading page numbers match */ if((i == (*a)->count) && (i == (*b)->count)) { /* all page numbers match */ /*********************************************************** We have identical entries, except possibly in encap fields. The ordering is tricky here. Consider the following input sequence of index names, encaps, and page numbers: foo|( 2 foo|) 6 foo|( 6 foo|) 10 This might legimately occur when a page range ends, and subsequently, a new range starts, on the same page. If we just order by range_open and range_close (here, parens), then we will produce foo|( 2 foo|( 6 foo|) 6 foo|) 10 This will later generate the index entry foo, 2--6, \({6}, 10 which is not only wrong, but has also introduced an illegal LaTeX macro, \({6}, because the merging step treated this like a \see{6} entry. The solution is to preserve the original input order, which we can do by treating range_open and range_close as equal, and then ordering by input line number. This will then generate the correct index entry foo, 2--10 Ordering inconsistencies from missing range open or close entries, or mixing roman and arabic page numbers, will be detected later. ***********************************************************/ #define isrange(c) ( ((c) == idx_ropen) || ((c) == idx_rclose) ) /* Order two range values by input line number */ if(isrange(*(*a)->encap) && isrange(*(*b)->encap)) m = (*a)->lc - (*b)->lc; /* Handle identical encap fields; neither is a range delimiter */ else if(STREQ((*a)->encap, (*b)->encap)) { /* If neither are yet marked duplicate, mark the second of them to be ignored. */ if(((*a)->type != DUPLICATE) && ((*b)->type != DUPLICATE)) (*b)->type = DUPLICATE; /* leave m == 0 to show equality */ } /* Encap fields differ: only one may be a range delimiter, */ /* or else neither of them is. If either of them is a range */ /* delimiter, order by input line number; otherwise, order */ /* by name. */ else { if(isrange(*(*a)->encap) || isrange(*(*b)->encap)) m = (*a)->lc - (*b)->lc; /* order by input line number */ else /* order non-range items by */ /* their encap strings */ m = compare_string((unsigned char*)((*a)->encap), (unsigned char*)((*b)->encap)); } } else if((i == (*a)->count) && (i < (*b)->count)) m = -1; else if((i < (*a)->count) && (i == (*b)->count)) m = 1; } return(m); }
int pdfmerge_main(int argc, char **argv) { pdf_write_options opts = { 0 }; char *output = "out.pdf"; char *infile_src; int c; while ((c = fz_getopt(argc, argv, "adlszo:")) != -1) { switch (c) { case 'o': output = fz_optarg; break; case 'a': opts.do_ascii ++; break; case 'd': opts.do_expand ^= PDF_EXPAND_ALL; break; case 'l': opts.do_linear ++; break; case 's': opts.do_clean ++; break; case 'z': opts.do_deflate ++; break; default: usage(); break; } } if (fz_optind == argc) usage(); ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "Cannot initialise context\n"); exit(1); } fz_try(ctx) { doc_des = pdf_create_document(ctx); } fz_catch(ctx) { fprintf(stderr, "Failed to allocate destination document file %s\n", output); exit(1); } /* Step through the source files */ while (fz_optind < argc) { fz_try(ctx) { infile_src = argv[fz_optind++]; pdf_drop_document(ctx, doc_src); doc_src = pdf_open_document(ctx, infile_src); if (fz_optind == argc || !isrange(argv[fz_optind])) merge_range("1-"); else merge_range(argv[fz_optind++]); } fz_catch(ctx) { fprintf(stderr, "Failed merging document %s\n", infile_src); exit(1); } } fz_try(ctx) { pdf_save_document(ctx, doc_des, output, &opts); } fz_always(ctx) { pdf_drop_document(ctx, doc_des); pdf_drop_document(ctx, doc_src); } fz_catch(ctx) { fprintf(stderr, "Error encountered during file save.\n"); exit(1); } fz_flush_warnings(ctx); fz_drop_context(ctx); return 0; }
bool Parserange_universal_iit (char **div, bool *revcomp, Genomicpos_T *genomicstart, Genomicpos_T *genomiclength, Genomicpos_T *chrstart, Genomicpos_T *chrend, Genomicpos_T *chroffset, Genomicpos_T *chrlength, char *query, IIT_T chromosome_iit, IIT_T contig_iit) { char *coords; Genomicpos_T result, left, length; Interval_T interval; int theindex; int rc; *revcomp = false; if (index(query,':')) { /* Segment must be a genome, chromosome, or contig */ debug(printf("Parsed query %s into ",query)); *div = strtok(query,":"); if ((*div)[0] == '+') { *revcomp = false; *div = &((*div)[1]); } else if ((*div)[0] == '_') { *revcomp = true; *div = &((*div)[1]); } coords = strtok(NULL,":"); debug(printf("segment %s and coords %s\n",*div,coords)); debug(printf("Interpreting segment %s as a chromosome\n",*div)); if (coords == NULL) { debug(printf(" entire chromosome\n")); rc = translate_chromosomepos_universal(&(*genomicstart),&(*genomiclength),*div,left=0,length=0,chromosome_iit); } else if (isnumberp(&result,coords)) { debug(printf(" and coords %s as a number\n",coords)); rc = translate_chromosomepos_universal(&(*genomicstart),&(*genomiclength),*div,left=result-1,length=1,chromosome_iit); } else if (isrange(&left,&length,&(*revcomp),coords)) { debug(printf(" and coords %s as a range starting at %u with length %u and revcomp = %d\n", coords,left,length,*revcomp)); rc = translate_chromosomepos_universal(&(*genomicstart),&(*genomiclength),*div,left,length,chromosome_iit); } else { debug(printf(" but coords %s is neither a number nor a range\n",coords)); rc = -1; } /* Compute chromosomal coordinates */ *chrstart = left; *chrend = *chrstart + *genomiclength; *chrstart += 1U; /* Make 1-based */ /* Get chromosomal information */ if ((theindex = IIT_find_one(chromosome_iit,*div)) < 0) { fprintf(stderr,"Cannot find chromosome %s in chromosome IIT file\n",*div); /* exit(9); */ } else { interval = IIT_interval(chromosome_iit,theindex); *chroffset = Interval_low(interval); *chrlength = Interval_length(interval); } if (rc != 0) { /* Try contig */ debug(printf("Interpreting segment %s as a contig\n",*div)); if (isnumberp(&result,coords)) { debug(printf(" and coords %s as a number\n",coords)); rc = translate_contig(&(*genomicstart),&(*genomiclength),*div,left=result-1,length=1,contig_iit); } else if (isrange(&left,&length,&(*revcomp),coords)) { debug(printf(" and coords %s as a range starting at %u with length %u and revcomp = %d\n", coords,left,length,*revcomp)); rc = translate_contig(&(*genomicstart),&(*genomiclength),*div,left,length,contig_iit); } else { debug(printf(" but coords %s is neither a number nor a range\n",coords)); rc = -1; } } if (rc != 0) { fprintf(stderr,"Can't find coordinates %s:%s\n",*div,coords); return false; } else { return true; } } else { /* Query must be a genomic position, genomic range, or contig */ *chrstart = *chroffset = *chrlength = 0; debug(printf("Parsed query %s as atomic ",query)); if (isnumberp(&result,query)) { debug(printf("number\n")); *genomicstart = result-1; *genomiclength = 1; } else if (isrange(&left,&length,&(*revcomp),query)) { debug(printf("range\n")); *genomicstart = left; *genomiclength = length; } else { debug(printf("contig\n")); return false; #if 0 rc = translate_contig(&(*genomicstart),&(*genomiclength),query,left=0,length=0,contig_iit); IIT_free(&contig_iit); #endif } *div = convert_to_chrpos_iit(&(*chrstart),chromosome_iit,*genomicstart); *chrend = *chrstart + *genomiclength; *chrstart += 1U; /* Make 1-based */ /* Try chromosome first */ if ((theindex = IIT_find_one(chromosome_iit,*div)) < 0) { fprintf(stderr,"Cannot find chromosome %s in chromosome IIT file\n",*div); return false; } else { interval = IIT_interval(chromosome_iit,theindex); *chroffset = Interval_low(interval); *chrlength = Interval_length(interval); return true; } } }
bool Parserange_universal (char **div, bool *revcomp, Genomicpos_T *genomicstart, Genomicpos_T *genomiclength, Genomicpos_T *chrstart, Genomicpos_T *chrend, Genomicpos_T *chroffset, Genomicpos_T *chrlength, char *query, char *genomesubdir, char *fileroot) { char *coords, *filename; Genomicpos_T result, left, length; IIT_T chromosome_iit, contig_iit; Interval_T interval; int theindex; int rc; *revcomp = false; if (index(query,':')) { /* Segment must be a genome, chromosome, or contig */ debug(printf("Parsed query %s into ",query)); *div = strtok(query,":"); if ((*div)[0] == '+') { *revcomp = false; *div = &((*div)[1]); } else if ((*div)[0] == '_') { *revcomp = true; *div = &((*div)[1]); } coords = strtok(NULL,":"); debug(printf("segment %s and coords %s\n",*div,coords)); /* Try chromosome first */ filename = (char *) CALLOC(strlen(genomesubdir)+strlen("/")+strlen(fileroot)+ strlen(".chromosome.iit")+1,sizeof(char)); sprintf(filename,"%s/%s.chromosome.iit",genomesubdir,fileroot); chromosome_iit = IIT_read(filename,/*name*/NULL,/*readonlyp*/true,/*divread*/READ_ALL, /*divstring*/NULL,/*add_iit_p*/false,/*labels_read_p*/true); FREE(filename); debug(printf("Interpreting segment %s as a chromosome\n",*div)); if (coords == NULL) { debug(printf(" entire chromosome\n")); rc = translate_chromosomepos_universal(&(*genomicstart),&(*genomiclength),*div,left=0,length=0,chromosome_iit); } else if (isnumberp(&result,coords)) { debug(printf(" and coords %s as a number\n",coords)); rc = translate_chromosomepos_universal(&(*genomicstart),&(*genomiclength),*div,left=result-1,length=1,chromosome_iit); } else if (isrange(&left,&length,&(*revcomp),coords)) { debug(printf(" and coords %s as a range starting at %u with length %u and revcomp = %d\n", coords,left,length,*revcomp)); rc = translate_chromosomepos_universal(&(*genomicstart),&(*genomiclength),*div,left,length,chromosome_iit); } else { debug(printf(" but coords %s is neither a number nor a range\n",coords)); rc = -1; } /* Compute chromosomal coordinates */ *chrstart = left; *chrend = *chrstart + *genomiclength; *chrstart += 1U; /* Make 1-based */ /* Get chromosomal information */ if ((theindex = IIT_find_one(chromosome_iit,*div)) < 0) { fprintf(stderr,"Cannot find chromosome %s in chromosome IIT file\n",*div); /* exit(9); */ } else { interval = IIT_interval(chromosome_iit,theindex); *chroffset = Interval_low(interval); *chrlength = Interval_length(interval); } IIT_free(&chromosome_iit); #if 0 /* Contig IIT's are of type 1, which require some work to compute on current div-based scheme. Just abandoning for now. */ if (rc != 0) { /* Try contig */ filename = (char *) CALLOC(strlen(genomesubdir)+strlen("/")+strlen(fileroot)+ strlen(".contig.iit")+1,sizeof(char)); sprintf(filename,"%s/%s.contig.iit",genomesubdir,fileroot); contig_iit = IIT_read(filename,/*name*/NULL,/*readonlyp*/true,/*divread*/READ_ALL, /*divstring*/NULL,/*add_iit_p*/false,/*labels_read_p*/true); FREE(filename); debug(printf("Interpreting segment %s as a contig\n",*div)); if (coords == NULL) { debug(printf(" entire contig\n")); rc = translate_contig_universal(&(*genomicstart),&(*genomiclength),*div,left=0,length=0,chromosome_iit); } else if (isnumberp(&result,coords)) { debug(printf(" and coords %s as a number\n",coords)); rc = translate_contig(&(*genomicstart),&(*genomiclength),*div,left=result-1,length=1,contig_iit); } else if (isrange(&left,&length,&(*revcomp),coords)) { debug(printf(" and coords %s as a range starting at %u with length %u and revcomp = %d\n", coords,left,length,*revcomp)); rc = translate_contig(&(*genomicstart),&(*genomiclength),*div,left,length,contig_iit); } else { debug(printf(" but coords %s is neither a number nor a range\n",coords)); rc = -1; } IIT_free(&contig_iit); } #endif if (rc != 0) { fprintf(stderr,"Can't find coordinates %s:%s\n",*div,coords); return false; } else { return true; } } else { /* Query must be a genomic position, genomic range, or contig */ *chrstart = *chroffset = *chrlength = 0; debug(printf("Parsed query %s as atomic ",query)); if (isnumberp(&result,query)) { debug(printf("number\n")); *genomicstart = result-1; *genomiclength = 1; } else if (isrange(&left,&length,&(*revcomp),query)) { debug(printf("range\n")); *genomicstart = left; *genomiclength = length; } else { debug(printf("contig\n")); return false; #if 0 filename = (char *) CALLOC(strlen(genomesubdir)+strlen("/")+strlen(fileroot)+ strlen(".contig.iit")+1,sizeof(char)); sprintf(filename,"%s/%s.contig.iit",genomesubdir,fileroot); contig_iit = IIT_read(filename,/*name*/NULL,/*readonlyp*/true,/*divread*/READ_ALL, /*divstring*/NULL,/*add_iit_p*/false,/*labels_read_p*/true); FREE(filename); rc = translate_contig(&(*genomicstart),&(*genomiclength),query,left=0,length=0,contig_iit); IIT_free(&contig_iit); #endif } *div = convert_to_chrpos(&(*chrstart),genomesubdir,fileroot,*genomicstart); *chrend = *chrstart + *genomiclength; *chrstart += 1U; /* Make 1-based */ /* Try chromosome first */ filename = (char *) CALLOC(strlen(genomesubdir)+strlen("/")+strlen(fileroot)+ strlen(".chromosome.iit")+1,sizeof(char)); sprintf(filename,"%s/%s.chromosome.iit",genomesubdir,fileroot); chromosome_iit = IIT_read(filename,/*name*/NULL,/*readonlyp*/true,/*divread*/READ_ALL, /*divstring*/NULL,/*add_iit_p*/false,/*labels_read_p*/true); FREE(filename); if ((theindex = IIT_find_one(chromosome_iit,*div)) < 0) { fprintf(stderr,"Cannot find chromosome %s in chromosome IIT file\n",*div); IIT_free(&chromosome_iit); return false; } else { interval = IIT_interval(chromosome_iit,theindex); *chroffset = Interval_low(interval); *chrlength = Interval_length(interval); IIT_free(&chromosome_iit); return true; } } }
bool Parserange_query (char **divstring, unsigned int *coordstart, unsigned int *coordend, bool *revcomp, char *query, char *filename) { char *coords; unsigned int result, left, length; int div_strlen; IIT_T iit; *divstring = NULL; *revcomp = false; if ((coords = find_div(&div_strlen,query,':')) != NULL) { /* Query may have a div */ *divstring = (char *) CALLOC(div_strlen+1,sizeof(char)); strncpy(*divstring,query,div_strlen); debug(printf("Parsed query %s into divstring %s and coords %s\n", query,*divstring,coords)); if (IIT_read_divint(filename,*divstring,/*add_iit_p*/true) < 0) { fprintf(stderr,"Chromosome %s not found in IIT file\n",*divstring); debug(printf(" but divstring not found, so treat as label\n")); FREE(*divstring); /* free only when returning false */ return false; } else if (coords == NULL || *coords == '\0') { debug(printf(" entire div\n")); if ((iit = IIT_read(filename,/*name*/NULL,/*readonlyp*/true,/*divread*/READ_ONE,*divstring, /*add_iit_p*/true,/*labels_read_p*/false)) == NULL) { if (Access_file_exists_p(filename) == false) { fprintf(stderr,"Cannot read file %s\n",filename); } else { fprintf(stderr,"File %s appears to be an invalid IIT file\n",filename); } exit(9); } else { *coordstart= 0; *coordend = IIT_divlength(iit,*divstring); debug(printf(" divlength is %u\n",*coordend)); IIT_free(&iit); } return true; } else if (isnumberp(&result,coords)) { debug(printf(" and coords %s as a number\n",coords)); *coordstart = result; *coordend = result; return true; } else if (isrange(&left,&length,&(*revcomp),coords)) { debug(printf(" and coords %s as a range starting at %u with length %u and revcomp = %d\n", coords,left,length,*revcomp)); *coordstart = left + 1; /* Because isrange is 0-based */ *coordend = left + length; return true; } else { debug(printf(" but coords %s is neither a number nor a range. Interpret as a label.\n",coords)); FREE(*divstring); /* free only when returning false */ return false; } } else { /* No div. Query must be a number, range, or label */ debug(printf("Parsed query %s without a div ",query)); if (isnumberp(&result,query)) { debug(printf("number\n")); *coordstart = result; *coordend = result; return true; } else if (isrange(&left,&length,&(*revcomp),query)) { debug(printf("range\n")); *coordstart = left + 1; /* Because isrange is 0-based */ *coordend = left + length; return true; } else { debug(printf("label\n")); return false; } } }
void write_weights (unsigned total, const wfa_t *wfa, bitfile_t *output) /* * Traverse the transition matrices of the 'wfa' and write #'total' * weights != 0 to stream 'output'. * * No return value. */ { unsigned state, label; /* current label */ unsigned offset1, offset2; /* model offsets. */ unsigned offset3, offset4; /* model offsets. */ unsigned *weights_array; /* array of weights to encode */ unsigned *wptr; /* pointer to current weight */ unsigned *level_array; /* array of corresponding levels */ unsigned *lptr; /* pointer to current corr. level */ int min_level, max_level; /* min and max range level */ int d_min_level, d_max_level; /* min and max delta range level */ bool_t dc, d_dc; /* true if dc or delta dc are used */ bool_t delta_approx = NO; /* true if delta has been used */ unsigned delta_count = 0; /* number of delta ranges */ unsigned bits = bits_processed (output); /* * Check whether delta approximation has been used */ for (state = wfa->basis_states; state < wfa->states; state++) if (wfa->delta_state [state]) { delta_approx = YES; break; } /* * Generate array of corresponding levels (context of probability model) */ min_level = d_min_level = MAXLEVEL; max_level = d_max_level = 0; dc = d_dc = NO; for (state = wfa->basis_states; state < wfa->states; state++) for (label = 0; label < MAXLABELS; label++) if (isrange (wfa->tree [state][label])) { if (delta_approx && wfa->delta_state [state]) /* delta approx. */ { d_min_level = min (d_min_level, wfa->level_of_state [state] - 1); d_max_level = max (d_max_level, wfa->level_of_state [state] - 1); if (wfa->into [state][label][0] == 0) d_dc = YES; } else { min_level = min (min_level, wfa->level_of_state [state] - 1); max_level = max (max_level, wfa->level_of_state [state] - 1); if (wfa->into [state][label][0] == 0) dc = YES; } } if (min_level > max_level) /* no lc found */ max_level = min_level - 1; if (d_min_level > d_max_level) d_max_level = d_min_level - 1; /* * Context model: * 0 DC weight * 1 Delta DC weight * 2-k normal weights per level * k+1 - m Delta weights per level */ offset1 = dc ? 1 : 0; offset2 = offset1 + (d_dc ? 1 : 0); offset3 = offset2 + (max_level - min_level + 1); offset4 = offset3 + (d_max_level - d_min_level + 1); /* * Weights are encoded as follows: * all weights of state n * sorted by label * sorted by domain number */ wptr = weights_array = Calloc (total, sizeof (unsigned)); lptr = level_array = Calloc (total, sizeof (unsigned)); for (state = wfa->basis_states; state < wfa->states; state++) for (label = 0; label < MAXLABELS; label++) if (isrange (wfa->tree [state][label])) { int edge; /* current edge */ int domain; /* current domain (context of model) */ for (edge = 0; isedge (domain = wfa->into [state][label][edge]); edge++) { if (wptr - weights_array >= (int) total) error ("Can't write more than %d weights.", total); if (domain) /* not DC component */ { if (delta_approx && wfa->delta_state [state]) /* delta */ { *wptr++ = rtob (wfa->weight [state][label][edge], wfa->wfainfo->d_rpf); *lptr++ = offset3 + wfa->level_of_state [state] - 1 - d_min_level; delta_count++; } else { *wptr++ = rtob (wfa->weight [state][label][edge], wfa->wfainfo->rpf); *lptr++ = offset2 + wfa->level_of_state [state] - 1 - min_level; } } else /* DC component */ { if (delta_approx && wfa->delta_state [state]) /* delta */ { *wptr++ = rtob (wfa->weight [state][label][edge], wfa->wfainfo->d_dc_rpf); *lptr++ = offset1; } else { *wptr++ = rtob (wfa->weight [state][label][edge], wfa->wfainfo->dc_rpf); *lptr++ = 0; } } } } { unsigned i; unsigned *c_symbols = Calloc (offset4, sizeof (int)); const int scale = 500; /* scaling of probability model */ c_symbols [0] = 1 << (wfa->wfainfo->dc_rpf->mantissa_bits + 1); if (offset1 != offset2) c_symbols [offset1] = 1 << (wfa->wfainfo->d_dc_rpf->mantissa_bits + 1); for (i = offset2; i < offset3; i++) c_symbols [i] = 1 << (wfa->wfainfo->rpf->mantissa_bits + 1); for (; i < offset4; i++) c_symbols [i] = 1 << (wfa->wfainfo->d_rpf->mantissa_bits + 1); encode_array (output, weights_array, level_array, c_symbols, offset4, total, scale); Free (c_symbols); } debug_message ("%d delta weights out of %d.", delta_count, total); debug_message ("weights: %5d bits. (%5d symbols => %5.2f bps)", bits_processed (output) - bits, total, (bits_processed (output) - bits) / (double) total); Free (weights_array); Free (level_array); }
int main(int argc, char **argv) { int grayscale = 0; int accelerate = 1; xps_context *ctx; int code; int c; while ((c = fz_getopt(argc, argv, "o:p:r:Aadglmtx5")) != -1) { switch (c) { case 'o': output = fz_optarg; break; case 'r': resolution = atof(fz_optarg); break; case 'A': accelerate = 0; break; case 'a': savealpha = 1; break; case 'l': showoutline++; break; case 'm': showtime++; break; case 't': showtext++; break; case 'x': showxml++; break; case '5': showmd5++; break; case 'g': grayscale++; break; case 'd': uselist = 0; break; default: usage(); break; } } if (fz_optind == argc) usage(); if (!showtext && !showxml && !showtime && !showmd5 && !showoutline && !output) { printf("nothing to do\n"); exit(0); } if (accelerate) fz_accelerate(); glyphcache = fz_new_glyph_cache(); colorspace = fz_device_rgb; if (grayscale) colorspace = fz_device_gray; if (output && strstr(output, ".pgm")) colorspace = fz_device_gray; if (output && strstr(output, ".ppm")) colorspace = fz_device_rgb; timing.count = 0; timing.total = 0; timing.min = 1 << 30; timing.max = 0; timing.minpage = 0; timing.maxpage = 0; if (showxml) printf("<?xml version=\"1.0\"?>\n"); while (fz_optind < argc) { filename = argv[fz_optind++]; code = xps_open_file(&ctx, filename); if (code) die(fz_rethrow(code, "cannot open document: %s", filename)); if (showxml) printf("<document name=\"%s\">\n", filename); if (showoutline) drawoutline(ctx); if (showtext || showxml || showtime || showmd5 || output) { if (fz_optind == argc || !isrange(argv[fz_optind])) drawrange(ctx, "1-"); if (fz_optind < argc && isrange(argv[fz_optind])) drawrange(ctx, argv[fz_optind++]); } if (showxml) printf("</document>\n"); xps_free_context(ctx); } if (showtime) { printf("total %dms / %d pages for an average of %dms\n", timing.total, timing.count, timing.total / timing.count); printf("fastest page %d: %dms\n", timing.minpage, timing.min); printf("slowest page %d: %dms\n", timing.maxpage, timing.max); } fz_free_glyph_cache(glyphcache); return 0; }
void read_weights (unsigned total, wfa_t *wfa, bitfile_t *input) /* * Read #'total' weights from input stream 'input' and * update transitions of the WFA states with corresponding weights. * * No return value. * * Side effects: * 'wfa->weights' are filled with the decoded values */ { unsigned state; unsigned label; unsigned edge; /* current edge */ unsigned *weights_array; /* array of weights to encode */ unsigned *level_array; /* array of corresponding levels */ unsigned offset1, offset2; /* prob. model offsets. */ unsigned offset3, offset4; /* prob. model offsets. */ bool_t delta_approx = NO; /* true if delta has been used */ /* * Check whether delta approximation has been used */ for (state = wfa->basis_states; state < wfa->states; state++) if (wfa->delta_state [state]) { delta_approx = YES; break; } /* * Generate array of corresponding levels (context of probability model) */ { int min_level, max_level; /* min and max range level */ int d_min_level, d_max_level; /* min and max range level (delta) */ unsigned *lptr; /* pointer to current corresp. level */ int domain; /* current domain */ bool_t dc, d_dc; /* indicates whether DC is used */ /* * Compute minimum and maximum level of delta and normal approximations */ min_level = d_min_level = MAXLEVEL; max_level = d_max_level = 0; dc = d_dc = NO; for (state = wfa->basis_states; state < wfa->states; state++) for (label = 0; label < MAXLABELS; label++) if (isrange (wfa->tree [state][label])) { if (delta_approx && wfa->delta_state [state]) { d_min_level = min (d_min_level, wfa->level_of_state [state] - 1); d_max_level = max (d_max_level, wfa->level_of_state [state] - 1); if (wfa->into [state][label][0] == 0) d_dc = YES; } else { min_level = min (min_level, wfa->level_of_state [state] - 1); max_level = max (max_level, wfa->level_of_state [state] - 1); if (wfa->into [state][label][0] == 0) dc = YES; } } if (min_level > max_level) /* no lc found */ max_level = min_level - 1; if (d_min_level > d_max_level) d_max_level = d_min_level - 1; offset1 = dc ? 1 : 0; offset2 = offset1 + (d_dc ? 1 : 0); offset3 = offset2 + (max_level - min_level + 1); offset4 = offset3 + (d_max_level - d_min_level + 1); lptr = level_array = Calloc (total, sizeof (int)); for (state = wfa->basis_states; state < wfa->states; state++) for (label = 0; label < MAXLABELS; label++) if (isrange (wfa->tree[state][label])) for (edge = 0; isedge (domain = wfa->into[state][label][edge]); edge++) { if ((unsigned) (lptr - level_array) >= total) error ("Can't read more than %d weights.", total); if (domain) { if (delta_approx && wfa->delta_state [state]) *lptr++ = offset3 + wfa->level_of_state [state] - 1 - d_min_level; else *lptr++ = offset2 + wfa->level_of_state [state] - 1 - min_level; } else *lptr++ = delta_approx && wfa->delta_state [state] ? offset1 : 0; } } /* * Decode the list of weights with an arithmetic decoder */ { unsigned i; unsigned *c_symbols = Calloc (offset4, sizeof (unsigned)); const unsigned scale = 500; /* scaling of probability model */ c_symbols [0] = 1 << (wfa->wfainfo->dc_rpf->mantissa_bits + 1); if (offset1 != offset2) c_symbols [offset1] = 1 << (wfa->wfainfo->d_dc_rpf->mantissa_bits + 1); for (i = offset2; i < offset3; i++) c_symbols [i] = 1 << (wfa->wfainfo->rpf->mantissa_bits + 1); for (; i < offset4; i++) c_symbols [i] = 1 << (wfa->wfainfo->d_rpf->mantissa_bits + 1); weights_array = decode_array (input, level_array, c_symbols, offset4, total, scale); Free (c_symbols); } Free (level_array); /* * Update transitions with decoded weights */ { unsigned *wptr = weights_array; /* pointer to current weight */ int domain; /* current domain */ for (state = wfa->basis_states; state < wfa->states; state++) for (label = 0; label < MAXLABELS; label++) if (isrange (wfa->tree[state][label])) for (edge = 0; isedge (domain = wfa->into[state][label][edge]); edge++) { if (domain) /* not DC component */ { if (delta_approx && wfa->delta_state [state]) wfa->weight [state][label][edge] = btor (*wptr++, wfa->wfainfo->d_rpf); else wfa->weight [state][label][edge] = btor (*wptr++, wfa->wfainfo->rpf); } else { if (delta_approx && wfa->delta_state [state]) wfa->weight [state][label][edge] = btor (*wptr++, wfa->wfainfo->d_dc_rpf); else wfa->weight [state][label][edge] = btor (*wptr++, wfa->wfainfo->dc_rpf); } wfa->int_weight [state][label][edge] = wfa->weight [state][label][edge] * 512 + 0.5; } } Free (weights_array); }