| | 109 | |
|---|
| | 110 | cdef extern from "gd.h": |
|---|
| | 111 | ctypedef struct gdImagePtr "gdImagePtr": |
|---|
| | 112 | pass |
|---|
| | 113 | |
|---|
| | 114 | gdImagePtr gdImageCreateFromPng(FILE *f) |
|---|
| | 115 | gdImagePtr gdImageCreateFromPngPtr(int size, void *s) |
|---|
| | 116 | gdImagePtr gdImageCreate(int x, int y) |
|---|
| | 117 | void gdImagePng(gdImagePtr im, FILE *out) |
|---|
| | 118 | void *gdImagePngPtr(gdImagePtr im, int *size) |
|---|
| | 119 | void gdImageDestroy(gdImagePtr im) |
|---|
| | 120 | int gdImageSX(gdImagePtr im) |
|---|
| | 121 | int gdImageSY(gdImagePtr im) |
|---|
| | 122 | int gdImageGetPixel(gdImagePtr im, int x, int y) |
|---|
| | 123 | void gdImageSetPixel(gdImagePtr im, int x, int y, int value) |
|---|
| | 124 | int gdImageColorAllocate(gdImagePtr im, int r, int g, int b) |
|---|
| | 125 | void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color) |
|---|
| | 126 | void gdFree(void *m) |
|---|
| | 1225 | def __reduce__(self): |
|---|
| | 1226 | r""" |
|---|
| | 1227 | Serialize \code{self}. |
|---|
| | 1228 | |
|---|
| | 1229 | EXAMPLE: |
|---|
| | 1230 | sage: A = random_matrix(GF(2),10,10) |
|---|
| | 1231 | sage: f,s = A.__reduce__() |
|---|
| | 1232 | sage: f(*s) == A |
|---|
| | 1233 | True |
|---|
| | 1234 | """ |
|---|
| | 1235 | cdef int i,j, r,c, size |
|---|
| | 1236 | |
|---|
| | 1237 | r, c = self.nrows(), self.ncols() |
|---|
| | 1238 | if r == 0 or c == 0: |
|---|
| | 1239 | return unpickle_matrix_mod2_dense_v1, (r, c, None, 0) |
|---|
| | 1240 | |
|---|
| | 1241 | _sig_on |
|---|
| | 1242 | cdef gdImagePtr im = gdImageCreate(c, r) |
|---|
| | 1243 | _sig_off |
|---|
| | 1244 | cdef int black = gdImageColorAllocate(im, 0, 0, 0) |
|---|
| | 1245 | cdef int white = gdImageColorAllocate(im, 255, 255, 255) |
|---|
| | 1246 | gdImageFilledRectangle(im, 0, 0, c-1, r-1, white) |
|---|
| | 1247 | for i from 0 <= i < r: |
|---|
| | 1248 | for j from 0 <= j < c: |
|---|
| | 1249 | if mzd_read_bit(self._entries, i, j): |
|---|
| | 1250 | gdImageSetPixel(im, j, i, black ) |
|---|
| | 1251 | |
|---|
| | 1252 | cdef char *buf = <char*>gdImagePngPtr(im, &size) |
|---|
| | 1253 | |
|---|
| | 1254 | data = [buf[i] for i in range(size)] |
|---|
| | 1255 | gdFree(buf) |
|---|
| | 1256 | return unpickle_matrix_mod2_dense_v1, (r,c, data, size) |
|---|
| | 1257 | |
|---|
| | 1258 | def unpickle_matrix_mod2_dense_v1(r, c, data, size): |
|---|
| | 1259 | r""" |
|---|
| | 1260 | Deserialize a matrix encoded in the string \code{s}. |
|---|
| | 1261 | |
|---|
| | 1262 | INPUT: |
|---|
| | 1263 | r -- number of rows of matrix |
|---|
| | 1264 | c -- number of columns of matrix |
|---|
| | 1265 | s -- a string |
|---|
| | 1266 | size -- length of the string s |
|---|
| | 1267 | |
|---|
| | 1268 | EXAMPLE: |
|---|
| | 1269 | sage: A = random_matrix(GF(2),100,101) |
|---|
| | 1270 | sage: _,(r,c,s,s2) = A.__reduce__() |
|---|
| | 1271 | sage: from sage.matrix.matrix_mod2_dense import unpickle_matrix_mod2_dense_v1 |
|---|
| | 1272 | sage: unpickle_matrix_mod2_dense_v1(r,c,s,s2) == A |
|---|
| | 1273 | True |
|---|
| | 1274 | sage: loads(dumps(A)) == A |
|---|
| | 1275 | True |
|---|
| | 1276 | """ |
|---|
| | 1277 | from sage.matrix.constructor import Matrix |
|---|
| | 1278 | from sage.rings.finite_field import FiniteField as GF |
|---|
| | 1279 | |
|---|
| | 1280 | cdef int i, j |
|---|
| | 1281 | cdef Matrix_mod2_dense A |
|---|
| | 1282 | |
|---|
| | 1283 | A = <Matrix_mod2_dense>Matrix(GF(2),r,c) |
|---|
| | 1284 | if r == 0 or c == 0: |
|---|
| | 1285 | return A |
|---|
| | 1286 | |
|---|
| | 1287 | cdef char *buf = <char*>sage_malloc(size) |
|---|
| | 1288 | for i from 0 <= i < size: |
|---|
| | 1289 | buf[i] = data[i] |
|---|
| | 1290 | |
|---|
| | 1291 | _sig_on |
|---|
| | 1292 | cdef gdImagePtr im = gdImageCreateFromPngPtr(size, buf) |
|---|
| | 1293 | _sig_off |
|---|
| | 1294 | |
|---|
| | 1295 | sage_free(buf) |
|---|
| | 1296 | |
|---|
| | 1297 | if gdImageSX(im) != c or gdImageSY(im) != r: |
|---|
| | 1298 | raise TypeError, "Pickled data dimension doesn't match." |
|---|
| | 1299 | |
|---|
| | 1300 | |
|---|
| | 1301 | for i from 0 <= i < r: |
|---|
| | 1302 | for j from 0 <= j < c: |
|---|
| | 1303 | mzd_write_bit(A._entries, i, j, 1-gdImageGetPixel(im, j, i)) |
|---|
| | 1304 | gdImageDestroy(im) |
|---|
| | 1305 | return A |
|---|
| | 1306 | |
|---|
| | 1307 | def from_png(filename): |
|---|
| | 1308 | r""" |
|---|
| | 1309 | Returns a dense matrix over GF(2) from a 1-bit PNG image read from |
|---|
| | 1310 | \code{filename}. No attempt is made to verify that the filname string |
|---|
| | 1311 | actually points to a PNG image. |
|---|
| | 1312 | |
|---|
| | 1313 | INPUT: |
|---|
| | 1314 | filename -- a string |
|---|
| | 1315 | |
|---|
| | 1316 | EXAMPLE: |
|---|
| | 1317 | sage: from sage.matrix.matrix_mod2_dense import from_png, to_png |
|---|
| | 1318 | sage: A = random_matrix(GF(2),10,10) |
|---|
| | 1319 | sage: fn = tmp_filename() |
|---|
| | 1320 | sage: to_png(A, fn) |
|---|
| | 1321 | sage: B = from_png(fn) |
|---|
| | 1322 | sage: A == B |
|---|
| | 1323 | True |
|---|
| | 1324 | """ |
|---|
| | 1325 | from sage.matrix.constructor import Matrix |
|---|
| | 1326 | from sage.rings.finite_field import FiniteField as GF |
|---|
| | 1327 | |
|---|
| | 1328 | cdef int i,j,r,c |
|---|
| | 1329 | cdef Matrix_mod2_dense A |
|---|
| | 1330 | |
|---|
| | 1331 | fn = open(filename,"r") # check filename |
|---|
| | 1332 | fn.close() |
|---|
| | 1333 | |
|---|
| | 1334 | cdef FILE *f = fopen(filename, "rb") |
|---|
| | 1335 | _sig_on |
|---|
| | 1336 | cdef gdImagePtr im = gdImageCreateFromPng(f) |
|---|
| | 1337 | _sig_off |
|---|
| | 1338 | |
|---|
| | 1339 | c, r = gdImageSX(im), gdImageSY(im) |
|---|
| | 1340 | |
|---|
| | 1341 | A = <Matrix_mod2_dense>Matrix(GF(2),r,c) |
|---|
| | 1342 | |
|---|
| | 1343 | for i from 0 <= i < r: |
|---|
| | 1344 | for j from 0 <= j < c: |
|---|
| | 1345 | mzd_write_bit(A._entries, i, j, 1-gdImageGetPixel(im, j, i)) |
|---|
| | 1346 | fclose(f) |
|---|
| | 1347 | gdImageDestroy(im) |
|---|
| | 1348 | return A |
|---|
| | 1349 | |
|---|
| | 1350 | def to_png(Matrix_mod2_dense A, filename): |
|---|
| | 1351 | r""" |
|---|
| | 1352 | Saves the matrix \code{A} to filename as a 1-bit PNG image. |
|---|
| | 1353 | |
|---|
| | 1354 | INPUT: |
|---|
| | 1355 | A -- a matrix over GF(2) |
|---|
| | 1356 | filename -- a string for a file in a writeable position |
|---|
| | 1357 | |
|---|
| | 1358 | EXAMPLE: |
|---|
| | 1359 | sage: from sage.matrix.matrix_mod2_dense import from_png, to_png |
|---|
| | 1360 | sage: A = random_matrix(GF(2),10,10) |
|---|
| | 1361 | sage: fn = tmp_filename() |
|---|
| | 1362 | sage: to_png(A, fn) |
|---|
| | 1363 | sage: B = from_png(fn) |
|---|
| | 1364 | sage: A == B |
|---|
| | 1365 | True |
|---|
| | 1366 | """ |
|---|
| | 1367 | cdef int i,j, r,c |
|---|
| | 1368 | r, c = A.nrows(), A.ncols() |
|---|
| | 1369 | if r == 0 or c == 0: |
|---|
| | 1370 | raise TypeError, "Cannot write image with dimensions %d x %d"%(c,r) |
|---|
| | 1371 | fn = open(filename,"w") # check filename |
|---|
| | 1372 | fn.close() |
|---|
| | 1373 | cdef gdImagePtr im = gdImageCreate(c, r) |
|---|
| | 1374 | cdef FILE * out = fopen(filename, "wb") |
|---|
| | 1375 | cdef int black = gdImageColorAllocate(im, 0, 0, 0) |
|---|
| | 1376 | cdef int white = gdImageColorAllocate(im, 255, 255, 255) |
|---|
| | 1377 | gdImageFilledRectangle(im, 0, 0, c-1, r-1, white) |
|---|
| | 1378 | for i from 0 <= i < r: |
|---|
| | 1379 | for j from 0 <= j < c: |
|---|
| | 1380 | if mzd_read_bit(A._entries, i, j): |
|---|
| | 1381 | gdImageSetPixel(im, j, i, black ) |
|---|
| | 1382 | |
|---|
| | 1383 | gdImagePng(im, out) |
|---|
| | 1384 | gdImageDestroy(im) |
|---|
| | 1385 | fclose(out) |