Exemplo n.º 1
0
char load(ImlibImage * im, ImlibProgressFunction progress,
          char progress_granularity, char immediate_load)
{
  uint8_t *data;
  size_t size;
  int w,h;
  int has_alpha;
#if (WEBP_DECODER_ABI_VERSION >= 0x200)
  WebPBitstreamFeatures features;
#endif
  char ret = 0;

  if(im->data)
    return 0;

  if(!(data = read_file(im->real_file, &size, progress)))
    return 0;

#if (WEBP_DECODER_ABI_VERSION >= 0x200)
  if(WebPGetFeatures(data, size, &features) != VP8_STATUS_OK)
    goto EXIT;
  w = features.width;
  h = features.height;
  has_alpha = features.has_alpha;
#else /* compatibility with versions <= 0.1.3 */
  if (!WebPGetInfo(data, size, &w, &h))
    goto EXIT;
  has_alpha = 0;
#endif

  if(!im->loader && !im->data) {
    im->w = w;
    im->h = h;

    if(!IMAGE_DIMENSIONS_OK(w, h))
      goto EXIT;

    if(!has_alpha)
      UNSET_FLAGS(im->flags, F_HAS_ALPHA);
    else
      SET_FLAGS(im->flags, F_HAS_ALPHA);
    im->format = strdup("webp");
  }

  if((!im->data && im->loader) || immediate_load || progress)
     im->data = (DATA32*)WebPDecodeBGRA(data, size, &w, &h);

  if(progress)
    progress(im, 100, 0, 0, 0, 0);

  ret = 1;

EXIT:
  free(data);
  return ret;
}
Exemplo n.º 2
0
char
load(ImlibImage * im, ImlibProgressFunction progress,
     char progress_granularity, char immediate_load)
{
   int                 w = 0, h = 0, alpha = 0;
   FILE               *f;

   if (im->data)
      return 0;
   f = fopen(im->real_file, "rb");
   if (!f)
      return 0;

   /* header */
   {
      char                buf[256], buf2[256];

      buf[0] = '\0';
      if (!fgets(buf, 255, f))
        {
           fclose(f);
           return 0;
        }
      buf2[0] = '\0';
      sscanf(buf, "%s %i %i %i", buf2, &w, &h, &alpha);
      if (strcmp(buf2, "ARGB"))
        {
           fclose(f);
           return 0;
        }
      if (!IMAGE_DIMENSIONS_OK(w, h))
        {
           fclose(f);
           return 0;
        }
      im->w = w;
      im->h = h;
      if (!im->format)
        {
           if (alpha)
              SET_FLAG(im->flags, F_HAS_ALPHA);
           else
              UNSET_FLAG(im->flags, F_HAS_ALPHA);
           im->format = strdup("argb");
        }
   }
   if (((!im->data) && (im->loader)) || (immediate_load) || (progress))
     {
        DATA32             *ptr;
        int                 y, pl = 0;
        char                pper = 0;

        /* must set the im->data member before callign progress function */
        ptr = im->data = malloc(w * h * sizeof(DATA32));
        if (!im->data)
          {
             fclose(f);
             return 0;
          }
        for (y = 0; y < h; y++)
          {
#ifdef WORDS_BIGENDIAN
             {
                int                 x;

                if (fread(ptr, im->w, 4, f) != 4)
                  {
                     free(ptr);
                     fclose(f);
                     return 0;
                  }
                for (x = 0; x < im->w; x++)
                   SWAP32(ptr[x]);
             }
#else
             if (fread(ptr, im->w, 4, f) != 4)
               {
                  free(ptr);
                  fclose(f);
                  return 0;
               }
#endif
             ptr += im->w;
             if (progress)
               {
                  char                per;
                  int                 l;

                  per = (char)((100 * y) / im->h);
                  if (((per - pper) >= progress_granularity) ||
                      (y == (im->h - 1)))
                    {
                       l = y - pl;
                       if (!progress(im, per, 0, (y - l), im->w, l))
                         {
                            fclose(f);
                            return 2;
                         }
                       pper = per;
                       pl = y;
                    }
               }
          }
     }
   fclose(f);
   return 1;
}
/* The load_jpeg function is based on Imlib2 loader. */
ngx_int_t ngx_http_small_light_load_jpeg(
          void **dest_data, int *width, int *height, const ngx_http_request_t *r,
          const char *filename, int hint_w, int hint_h)
{
    int                            w, h;
    struct jpeg_decompress_struct  cinfo;
    struct ImLib_JPEG_error_mgr    jerr;
    FILE                          *f;
    ngx_int_t                      fd;
    int                            denom;
    DATA8                         *ptr, *line[16], *data;
    DATA32                        *ptr2, *dest;
    int                            x, y, l, i, scans;

    *dest_data = NULL;
    *width = *height = 0;

    fd = ngx_open_file(filename, NGX_FILE_RDONLY, NGX_FILE_OPEN, NGX_FILE_DEFAULT_ACCESS);
    if (fd == NGX_INVALID_FILE) {
        return NGX_ERROR;
    }
    f = fdopen(fd, "rb");

    cinfo.err = jpeg_std_error(&(jerr.pub));
    jerr.pub.error_exit = _JPEGFatalErrorHandler;
    jerr.pub.emit_message = _JPEGErrorHandler2;
    jerr.pub.output_message = _JPEGErrorHandler;
    if (sigsetjmp(jerr.setjmp_buffer, 1)) {
        jpeg_destroy_decompress(&cinfo);
        ngx_close_file(fd);
        fclose(f);
        return NGX_ERROR;
    }
    jpeg_create_decompress(&cinfo);
    jpeg_stdio_src(&cinfo, f);
    jpeg_read_header(&cinfo, TRUE);
    cinfo.do_fancy_upsampling = FALSE;
    cinfo.do_block_smoothing = FALSE;

    jpeg_start_decompress(&cinfo);
    w = cinfo.output_width;
    h = cinfo.output_height;
    denom = w / hint_w;
    if (denom > h / hint_h) {
        denom = h / hint_h;
    }
    denom = denom >= 1 ? denom : 1;
    denom = denom <= 8 ? denom : 8;
    jpeg_destroy_decompress(&cinfo);
    fseek(f, 0, SEEK_SET);
    jpeg_create_decompress(&cinfo);
    jpeg_stdio_src(&cinfo, f);
    jpeg_read_header(&cinfo, TRUE);
    cinfo.do_fancy_upsampling = FALSE;
    cinfo.do_block_smoothing = FALSE;
    cinfo.scale_denom = denom;

    jpeg_start_decompress(&cinfo);

    w = cinfo.output_width;
    h = cinfo.output_height;

    if ((cinfo.rec_outbuf_height > 16) || (cinfo.output_components <= 0) ||
        !IMAGE_DIMENSIONS_OK(w, h))
    {
        jpeg_destroy_decompress(&cinfo);
        ngx_close_file(fd);
        fclose(f);
        return NGX_ERROR;
    }
    data = ngx_palloc(r->pool, w * 16 * cinfo.output_components);
    if (!data) {
        jpeg_destroy_decompress(&cinfo);
        ngx_close_file(fd);
        fclose(f);
        return NGX_ERROR;
    }
    /* must set the im->data member before callign progress function */
    ptr2 = dest = ngx_palloc(r->pool, w * h * sizeof(DATA32));
    if (!dest) {
        jpeg_destroy_decompress(&cinfo);
        ngx_close_file(fd);
        fclose(f);
        return NGX_ERROR;
    }
    if (cinfo.output_components > 1) {
        for (i = 0; i < cinfo.rec_outbuf_height; i++) {
            line[i] = data + (i * w * cinfo.output_components);
        }
        for (l = 0; l < h; l += cinfo.rec_outbuf_height) {
            jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
            scans = cinfo.rec_outbuf_height;
            if ((h - l) < scans) {
                scans = h - l;
            }
            ptr = data;
            for (y = 0; y < scans; y++) {
                for (x = 0; x < w; x++) {
                    *ptr2 =
                        (0xff000000)     |
                        ((ptr[0]) << 16) |
                        ((ptr[1]) <<  8) |
                        (ptr[2]);
                    ptr += cinfo.output_components;
                    ptr2++;
                }
            }
        }
    } else if (cinfo.output_components == 1) {
        for (i = 0; i < cinfo.rec_outbuf_height; i++) {
            line[i] = data + (i * w);
        }
        for (l = 0; l < h; l += cinfo.rec_outbuf_height) {
            jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
            scans = cinfo.rec_outbuf_height;
            if ((h - l) < scans) {
                scans = h - l;
            }
            ptr = data;
            for (y = 0; y < scans; y++) {
                for (x = 0; x < w; x++) {
                    *ptr2 =
                        (0xff000000)     |
                        ((ptr[0]) << 16) |
                        ((ptr[0]) <<  8) |
                        (ptr[0]);
                    ptr++;
                    ptr2++;
                }
            }
        }
    }

    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    ngx_close_file(fd);
    fclose(f);

    *dest_data = dest;
    *width = w;
    *height = h;

    return NGX_OK;
}
Exemplo n.º 4
0
/* \brief import TGA images */
int _glhckImportTGA(const char *file, _glhckImportImageStruct *import)
{
   FILE *f;
   void *seg = NULL, *data;
   int bpp, vinverted = 0;
   int rle = 0, footer_present = 0;
   size_t datasize, size;
   unsigned short i, w, h;
   tga_header *header;
   tga_footer *footer;
   unsigned char *bufptr, *bufend, *importData = NULL;
   CALL(0, "%s, %p", file, import);

   if (!(f = fopen(file, "rb")))
      goto read_fail;

   fseek(f, 0L, SEEK_END);
   if ((size = ftell(f)) < sizeof(tga_header) + sizeof(tga_footer))
      goto not_possible;

   if (!(seg = _glhckMalloc(size)))
      goto out_of_memory;

   fseek(f, 0L, SEEK_SET);
   if (fread(seg, 1, size, f) != size)
      goto fail;

   /* we don't need the file anymore */
   NULLDO(fclose, f);

   data = seg;
   header = (tga_header*)data;
   footer = (tga_footer*)((char*)data+size-sizeof(tga_footer));

   /* is TGA v2.0? (stop storing the headers at EOF please) */
   if (!memcmp(footer->signature, TGA_SIGNATURE, sizeof(footer->signature)))
      footer_present = 1;

   /* skip over header */
   data = (char*)data+sizeof(tga_header);

   /* skip over ID filed */
   if (header->idLength)
      data = (char*)data+header->idLength;

   /* inverted TGA? */
   vinverted = !(header->descriptor & TGA_DESC_VERTICAL);

   switch (header->imageType) {
      case TGA_TYPE_COLOR_RLE:
      case TGA_TYPE_GRAY_RLE:
         rle = 1;
         break;

      case TGA_TYPE_COLOR:
      case TGA_TYPE_GRAY:
         rle = 0;
         break;

      default:
         goto unknown_type;
   }

   bpp = header->bpp;
   if (!((bpp == 32) || (bpp == 24) || (bpp == 8)))
      goto invalid_bpp;

   /* endian safe for 16-bit dimensions */
   w = (header->widthHi  << 8) | header->widthLo;
   h = (header->heightHi << 8) | header->heightLo;

   if (!IMAGE_DIMENSIONS_OK(w, h))
      goto bad_dimensions;

   /* allocate destination buffer */
   if (!(importData = _glhckMalloc(w*h*4)))
      goto out_of_memory;

   /* find out how much data to be read from file
    * (this is NOT simply width*height*4, due to compression) */
   datasize = size - sizeof(tga_header) - header->idLength -
      (footer_present ? sizeof(tga_footer) : 0);

   /* bufptr is the next byte to be read from the buffer */
   bufptr = data;
   bufend = data + datasize;

   /* non RLE compressed data */
   if (!rle) {
      for (i = 0; i < h*w && bufptr+bpp/8 <= bufend; ++i) {
         switch (bpp) {
            /* 32-bit BGRA */
            case 32:
               importData[i*4+0] = bufptr[2];
               importData[i*4+1] = bufptr[1];
               importData[i*4+2] = bufptr[0];
               importData[i*4+3] = bufptr[3];
               bufptr += 4;
            break;

            /* 24-bit BGR */
            case 24:
               importData[i*4+0] = bufptr[2];
               importData[i*4+1] = bufptr[1];
               importData[i*4+2] = bufptr[0];
               importData[i*4+3] = 255;
               bufptr += 3;
            break;

            /* 8-bit grayscale */
            case 8:
               importData[i*4+0] = bufptr[0];
               importData[i*4+1] = bufptr[0];
               importData[i*4+2] = bufptr[0];
               importData[i*4+3] = 255;
               bufptr += 1;
            break;
         }
      }
   }

   /* RLE compressed data */
   if (rle) {
      DEBUG(GLHCK_DBG_ERROR, "RLE compressed import not yet implemented.");
      goto fail;
   }

   /* some TGA's are upside-down */
   if (vinverted) _glhckInvertPixels(importData, w, h, 4);

   /* free */
   NULLDO(_glhckFree, seg);

   /* fill import struct */
   import->width  = w;
   import->height = h;
   import->data   = importData;
   import->format = GLHCK_RGBA;
   import->type   = GLHCK_UNSIGNED_BYTE;
   import->flags |= (bpp==32?GLHCK_TEXTURE_IMPORT_ALPHA:0);
   RET(0, "%d", RETURN_OK);
   return RETURN_OK;

read_fail:
   DEBUG(GLHCK_DBG_ERROR, "Failed to open: %s", file);
   goto fail;
not_possible:
   DEBUG(GLHCK_DBG_ERROR, "Assumed TGA file '%s' has too small filesize", file);
   goto fail;
out_of_memory:
   DEBUG(GLHCK_DBG_ERROR, "Out of memory, won't load file: %s", file);
   goto fail;
unknown_type:
   DEBUG(GLHCK_DBG_ERROR, "Unknown TGA image type");
   goto fail;
invalid_bpp:
   DEBUG(GLHCK_DBG_ERROR, "TGA image is not either 32, 24 or 8 bpp");
   goto fail;
bad_dimensions:
   DEBUG(GLHCK_DBG_ERROR, "TGA image has invalid dimension %dx%d", w, h);
fail:
   IFDO(fclose, f);
   IFDO(_glhckFree, importData);
   IFDO(_glhckFree, seg);
   RET(0, "%d", RETURN_FAIL);
   return RETURN_FAIL;
}
Exemplo n.º 5
0
char
load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity,
     char immediate_load)
{
   DATA32             *ptr;
   GifFileType        *gif;
   GifRowType         *rows;
   GifRecordType       rec;
   ColorMapObject     *cmap;
   int                 i, j, done, bg, r, g, b, w = 0, h = 0;
   float               per = 0.0, per_inc;
   int                 last_per = 0, last_y = 0;
   int                 intoffset[] = { 0, 4, 2, 1 };
   int                 intjump[] = { 8, 8, 4, 2 };
   int                 transp;
   int                 fd;

   done = 0;
   rows = NULL;
   transp = -1;

   /* if immediate_load is 1, then dont delay image laoding as below, or */
   /* already data in this image - dont load it again */
   if (im->data)
      return 0;
#ifndef __EMX__
   fd = open(im->real_file, O_RDONLY);
#else
   fd = open(im->real_file, O_RDONLY | O_BINARY);
#endif
   if (fd < 0)
      return 0;
   gif = DGifOpenFileHandle(fd);
   if (!gif)
     {
        close(fd);
        return 0;
     }
   do
     {
        if (DGifGetRecordType(gif, &rec) == GIF_ERROR)
          {
             /* PrintGifError(); */
             rec = TERMINATE_RECORD_TYPE;
          }
        if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done))
          {
             if (DGifGetImageDesc(gif) == GIF_ERROR)
               {
                  /* PrintGifError(); */
                  rec = TERMINATE_RECORD_TYPE;
               }
             w = gif->Image.Width;
             h = gif->Image.Height;
             if (!IMAGE_DIMENSIONS_OK(w, h))
               {
                  DGifCloseFile(gif);
                  return 0;
               }
             rows = malloc(h * sizeof(GifRowType *));
             if (!rows)
               {
                  DGifCloseFile(gif);
                  return 0;
               }
             for (i = 0; i < h; i++)
               {
                  rows[i] = NULL;
               }
             for (i = 0; i < h; i++)
               {
                  rows[i] = malloc(w * sizeof(GifPixelType));
                  if (!rows[i])
                    {
                       DGifCloseFile(gif);
                       for (i = 0; i < h; i++)
                         {
                            if (rows[i])
                              {
                                 free(rows[i]);
                              }
                         }
                       free(rows);
                       return 0;
                    }
               }
             if (gif->Image.Interlace)
               {
                  for (i = 0; i < 4; i++)
                    {
                       for (j = intoffset[i]; j < h; j += intjump[i])
                         {
                            DGifGetLine(gif, rows[j], w);
                         }
                    }
               }
             else
               {
                  for (i = 0; i < h; i++)
                    {
                       DGifGetLine(gif, rows[i], w);
                    }
               }
             done = 1;
          }
        else if (rec == EXTENSION_RECORD_TYPE)
          {
             int                 ext_code;
             GifByteType        *ext;

             ext = NULL;
             DGifGetExtension(gif, &ext_code, &ext);
             while (ext)
               {
                  if ((ext_code == 0xf9) && (ext[1] & 1) && (transp < 0))
                    {
                       transp = (int)ext[4];
                    }
                  ext = NULL;
                  DGifGetExtensionNext(gif, &ext);
               }
          }
     }
   while (rec != TERMINATE_RECORD_TYPE);
   if (transp >= 0)
     {
        SET_FLAG(im->flags, F_HAS_ALPHA);
     }
   else
     {
        UNSET_FLAG(im->flags, F_HAS_ALPHA);
     }
   /* set the format string member to the lower-case full extension */
   /* name for the format - so example names would be: */
   /* "png", "jpeg", "tiff", "ppm", "pgm", "pbm", "gif", "xpm" ... */
   im->w = w;
   im->h = h;
   if (!im->format)
      im->format = strdup("gif");
   if (im->loader || immediate_load || progress)
     {
        bg = gif->SBackGroundColor;
        cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
        im->data = (DATA32 *) malloc(sizeof(DATA32) * w * h);
        if (!im->data)
          {
             DGifCloseFile(gif);
             free(rows);
             return 0;
          }
        ptr = im->data;
        per_inc = 100.0 / (((float)w) * h);
        for (i = 0; i < h; i++)
          {
             for (j = 0; j < w; j++)
               {
                  if (rows[i][j] == transp)
                    {
                       r = cmap->Colors[bg].Red;
                       g = cmap->Colors[bg].Green;
                       b = cmap->Colors[bg].Blue;
                       *ptr++ = 0x00ffffff & ((r << 16) | (g << 8) | b);
                    }
                  else
                    {
                       r = cmap->Colors[rows[i][j]].Red;
                       g = cmap->Colors[rows[i][j]].Green;
                       b = cmap->Colors[rows[i][j]].Blue;
                       *ptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
                    }
                  per += per_inc;
                  if (progress && (((int)per) != last_per)
                      && (((int)per) % progress_granularity == 0))
                    {
                       last_per = (int)per;
                       if (!(progress(im, (int)per, 0, last_y, w, i)))
                         {
                            DGifCloseFile(gif);
                            for (i = 0; i < h; i++)
                              {
                                 free(rows[i]);
                              }
                            free(rows);
                            return 2;
                         }
                       last_y = i;
                    }
               }
          }
     }
   if (progress)
     {
        progress(im, 100, 0, last_y, w, h);
     }
   DGifCloseFile(gif);
   for (i = 0; i < h; i++)
     {
        free(rows[i]);
     }
   free(rows);
   return 1;
}