src/lib/cache.c
changeset 6 766df7c9b90d
parent 4 49362b34116c
child 7 997906f5fd2d
equal deleted inserted replaced
5:4b440fa03183 6:766df7c9b90d
     1 #include "cache.h"
     1 #include "cache.h"
     2 #include "shared/util.h"
     2 #include "shared/util.h"
       
     3 #include "shared/log.h" // only LOG_DEBUG
     3 
     4 
     4 #include <stdlib.h>
     5 #include <stdlib.h>
     5 #include <unistd.h>
     6 #include <unistd.h>
     6 #include <sys/types.h>
     7 #include <sys/types.h>
     7 #include <sys/stat.h>
     8 #include <sys/stat.h>
     8 #include <fcntl.h>
     9 #include <fcntl.h>
     9 #include <sys/mman.h>
    10 #include <sys/mman.h>
    10 #include <errno.h>
    11 #include <errno.h>
       
    12 #include <assert.h>
    11 
    13 
    12 
    14 
    13 
    15 
    14 static int pt_cache_new (struct pt_cache **cache_ptr, const char *path, int mode)
    16 static int pt_cache_new (struct pt_cache **cache_ptr, const char *path, int mode)
    15 {
    17 {
    95 /**
    97 /**
    96  * Open the cache file as an fd for reading
    98  * Open the cache file as an fd for reading
    97  *
    99  *
    98  * XXX: needs locking
   100  * XXX: needs locking
    99  */
   101  */
   100 static int pt_cache_open_read (struct pt_cache *cache, int *fd_ptr)
   102 static int pt_cache_open_read_fd (struct pt_cache *cache, int *fd_ptr)
   101 {
   103 {
   102     int fd;
   104     int fd;
   103     
   105     
   104     // actual open()
   106     // actual open()
   105     if ((fd = open(cache->path, O_RDONLY)) < 0)
   107     if ((fd = open(cache->path, O_RDONLY)) < 0)
   112 }
   114 }
   113 
   115 
   114 /**
   116 /**
   115  * Open the .tmp cache file as an fd for writing
   117  * Open the .tmp cache file as an fd for writing
   116  */
   118  */
   117 static int pt_cache_open_tmp (struct pt_cache *cache, int *fd_ptr)
   119 static int pt_cache_open_tmp_fd (struct pt_cache *cache, int *fd_ptr)
   118 {
   120 {
   119     int fd;
   121     int fd;
   120     char tmp_path[1024];
   122     char tmp_path[1024];
   121     
   123     
   122     // check mode
   124     // check mode
   148 {
   150 {
   149     int prot = 0;
   151     int prot = 0;
   150     void *addr;
   152     void *addr;
   151 
   153 
   152     // determine prot
   154     // determine prot
   153     if (cache->mode & PT_IMG_READ)
   155     prot |= PROT_READ;
   154         prot |= PROT_READ;
       
   155 
   156 
   156     if (cache->mode & PT_IMG_WRITE)
   157     if (cache->mode & PT_IMG_WRITE)
   157         prot |= PROT_WRITE;
   158         prot |= PROT_WRITE;
   158 
   159 
   159     // perform mmap() from second page on
   160     // perform mmap() from second page on
   205         errno = EPERM;
   206         errno = EPERM;
   206         return -1;
   207         return -1;
   207     }
   208     }
   208 
   209 
   209     // open as .tmp
   210     // open as .tmp
   210     if (pt_cache_open_tmp(cache, &cache->fd))
   211     if (pt_cache_open_tmp_fd(cache, &cache->fd))
   211         return -1;
   212         return -1;
   212 
   213 
   213     // calculate data size
   214     // calculate data size
   214     cache->size = sizeof(*header) + header->height * header->row_bytes;
   215     cache->size = sizeof(*header) + header->height * header->row_bytes;
   215 
   216 
   267     header.width = png_get_image_width(png, info);
   268     header.width = png_get_image_width(png, info);
   268     header.height = png_get_image_height(png, info);
   269     header.height = png_get_image_height(png, info);
   269     header.bit_depth = png_get_bit_depth(png, info);
   270     header.bit_depth = png_get_bit_depth(png, info);
   270     header.color_type = png_get_color_type(png, info);
   271     header.color_type = png_get_color_type(png, info);
   271 
   272 
       
   273     log_debug("width=%u, height=%u, bit_depth=%u, color_type=%u", 
       
   274             header.width, header.height, header.bit_depth, header.color_type
       
   275     );
       
   276 
   272     // fill in other info
   277     // fill in other info
   273     header.row_bytes = png_get_rowbytes(png, info);
   278     header.row_bytes = png_get_rowbytes(png, info);
   274 
   279 
       
   280     log_debug("row_bytes=%u", header.row_bytes);
       
   281     
       
   282     // palette etc.
       
   283     if (header.color_type == PNG_COLOR_TYPE_PALETTE) {
       
   284         int num_palette;
       
   285         png_colorp palette;
       
   286 
       
   287         if (png_get_PLTE(png, info, &palette, &num_palette) == 0)
       
   288             // XXX: PLTE chunk not read?
       
   289             return -1;
       
   290         
       
   291         assert(num_palette <= PNG_MAX_PALETTE_LENGTH);
       
   292     
       
   293         // copy
       
   294         header.num_palette = num_palette;
       
   295         memcpy(&header.palette, palette, num_palette * sizeof(*palette));
       
   296         
       
   297         log_debug("num_palette=%u", num_palette);
       
   298     }
       
   299 
   275     // create .tmp and write out header
   300     // create .tmp and write out header
   276     if (pt_cache_open_create(cache, &header))
   301     if (pt_cache_open_create(cache, &header))
   277         return -1;
   302         return -1;
   278 
       
   279     // XXX: pallette etc.
       
   280 
   303 
   281     // write out raw image data a row at a time
   304     // write out raw image data a row at a time
   282     for (size_t row = 0; row < header.height; row++) {
   305     for (size_t row = 0; row < header.height; row++) {
   283         // read row data, non-interlaced
   306         // read row data, non-interlaced
   284         png_read_row(png, cache->mmap + row * header.row_bytes, NULL);
   307         png_read_row(png, cache->mmap + row * header.row_bytes, NULL);