static /* __inline__ */ int pdf_coord__idtransform (pdf_coord *p, const pdf_tmatrix *M) { pdf_tmatrix W; double x, y; int error; error = inversematrix(&W, M); if (error) return error; x = p->x; y = p->y; p->x = x * W.a + y * W.c; p->y = x * W.b + y * W.d; return 0; }
int pdf_dev_concat (const pdf_tmatrix *M) { m_stack *gss = &gs_stack; pdf_gstate *gs = m_stack_top(gss); pdf_path *cpa = &gs->path; pdf_coord *cpt = &gs->cp; pdf_tmatrix *CTM = &gs->matrix; pdf_tmatrix W = {0, 0, 0, 0, 0, 0}; /* Init to avoid compiler warning */ char *buf = fmt_buf; int len = 0; ASSERT(M); /* Adobe Reader erases page content if there are * non invertible transformation. */ if (fabs(detP(M)) < 1.0e-8) { WARN("Transformation matrix not invertible."); WARN("--- M = [%g %g %g %g %g %g]", M->a, M->b, M->c, M->d, M->e, M->f); return -1; } if (fabs(M->a - 1.0) > 1.e-8 || fabs(M->b) > 1.e-8 || fabs(M->c) > 1.e-8 || fabs(M->d - 1.0) > 1.e-8 || fabs(M->e) > 1.e-8 || fabs(M->f) > 1.e-8) { buf[len++] = ' '; len += pdf_sprint_matrix(buf + len, M); buf[len++] = ' '; buf[len++] = 'c'; buf[len++] = 'm'; pdf_doc_add_page_content(buf, len); /* op: cm */ pdf_concatmatrix(CTM, M); } inversematrix(&W, M); pdf_path__transform (cpa, &W); pdf_coord__transform(cpt, &W); return 0; }
// void determineiphi(graphs *graph, int gap, char *graphfile, int verbose) void determineiphi(graphs * graph, encoders * encoder, char *graphfile, int verbose) { int vnodenum, cnodenum; int row, col, node, socket; int temp, k; int *matrix, *extendedphi, *phi, *iphi; int gap; // copy encoders gap to internal gap for better readibility gap = (*encoder).gap; vnodenum = (*graph).vnodenum; cnodenum = (*graph).cnodenum; /* allocate memory */ matrix = (int *)allocate(vnodenum * gap * sizeof(int)); extendedphi = (int *)allocate(vnodenum * gap * sizeof(int)); phi = (int *)allocate(gap * gap * sizeof(int)); iphi = (int *)allocate(gap * gap * sizeof(int)); /* clear matrix */ for (row = 0; row < gap; row++) for (col = 0; col < vnodenum; col++) *(matrix + row * vnodenum + col) = 0; /* fill in the elements of the matrix */ if (verbose) printf("copy the last %d rows of H into matrix\n", gap); for (node = cnodenum - gap; node < cnodenum; node++) for (socket = 0; socket < cnodedegree; socket++) *(matrix + (node - cnodenum + gap) * vnodenum + cnodeedge.dest) = 1; if (verbose) { printhmatrix(graph); printmatrix(matrix, gap, vnodenum); } /* perform gaussian elimination on the last gap rows */ /* of the H matrix to clear E */ if (verbose) printf("do gaussian elimination\n"); node = cnodenum - gap - 1; for (col = vnodenum - 1; col > vnodenum - 1 - cnodenum + gap; col--) { for (row = 0; row < gap; row++) { if (*(matrix + row * vnodenum + col) == 1) { /* add the appropriate row of T */ for (socket = 0; socket < cnodedegree; socket++) *(matrix + row * vnodenum + cnodeedge.dest) ^= 1; } if (verbose) { printhmatrix(graph); printmatrix(matrix, gap, vnodenum); } } node--; } /* next we need ensure that the submatrix */ /* phi is not singular */ /* first copy matrix into extended phi */ for (row = 0; row < gap; row++) for (col = 0; col < vnodenum; col++) *(extendedphi + row * vnodenum + col) = *(matrix + row * vnodenum + col); row = -1; for (col = vnodenum - cnodenum + gap - 1; col > vnodenum - cnodenum - 1; col--) { row++; /* find a non zero entry */ node = col; while (*(matrix + row * vnodenum + node) != 1) { node--; if (node < 0) { printf("H matrix is rank deficient!\n"); exit(0); } } /* switch columns */ switchvnode(graph, col, node); for (k = 0; k < gap; k++) { temp = *(matrix + k * vnodenum + node); *(matrix + k * vnodenum + node) = *(matrix + k * vnodenum + col); *(matrix + k * vnodenum + col) = temp; } for (k = 0; k < gap; k++) { temp = *(extendedphi + k * vnodenum + node); *(extendedphi + k * vnodenum + node) = *(extendedphi + k * vnodenum + col); *(extendedphi + k * vnodenum + col) = temp; } if (verbose) { printf("after switch\n"); printmatrix(matrix, gap, vnodenum); } /* clear this column */ for (k = row + 1; k < gap; k++) { if (*(matrix + k * vnodenum + col) == 1) { for (node = col; node >= 0; node--) *(matrix + k * vnodenum + node) ^= *(matrix + row * vnodenum + node); } } if (verbose) { printf("after addition\n"); printmatrix(matrix, gap, vnodenum); } } /* we now know that phi is nonsingular */ for (row = 0; row < gap; row++) for (col = vnodenum - cnodenum; col < vnodenum - cnodenum + gap; col++) *(phi + row * gap + col - vnodenum + cnodenum) = *(extendedphi + row * vnodenum + col); if (verbose) { printf("phi matrix\n"); printmatrix(phi, gap, gap); } /* finally we need to determine the inverse of phi */ inversematrix(phi, iphi, gap); /* store the inverse etc in the file */ (*encoder).iphi = iphi; (*encoder).gap = gap; savegraph(graph, encoder, graphfile, 0); free(matrix); free(extendedphi); free(phi); free(iphi); }