Ejemplo n.º 1
0
        public static Response FromPartialStream(this IResponseFormatter response, Request request, Stream stream,
                                                 string contentType)
        {
            // Store the len
            var len = stream.Length;
            // Create the response now
            var res = response.FromStream(stream, contentType)
                      .WithHeader("Connection", "Keep-alive")
                      .WithHeader("Accept-ranges", "Bytes");

            // Use the partial status code
            res.StatusCode = HttpStatusCode.PartialContent;
            long startPos = 0;

            foreach (var s in request.Headers["Range"])
            {
                var start = s.Split('=')[1];
                var m     = Regex.Match(start, @"(\d+)-(\d+)?");
                start = m.Groups[1].Value;
                var end = len - 1;
                if (!string.IsNullOrWhiteSpace(m.Groups[2]?.Value))
                {
                    end = Convert.ToInt64(m.Groups[2].Value);
                }

                startPos = Convert.ToInt64(start);
                var length = len - startPos;
                res.WithHeader("Content-range", "Bytes " + start + "-" + end + "/" + len);
                res.WithHeader("Content-length", length.ToString(CultureInfo.InvariantCulture));
            }
            stream.Seek(startPos, SeekOrigin.Begin);
            return(res);
        }
Ejemplo n.º 2
0
        public static Response GetIcon(string key, IResponseFormatter response)
        {
            var image = ComicBook.PublisherIcons.GetImage(key);

            if (image == null)
            {
                return(response.AsRedirect("/original/Views/spacer.png"));
            }
            return(response.FromStream(GetBytesFromImage(image), MimeTypes.GetMimeType(".jpg")));
        }
Ejemplo n.º 3
0
		public static Response WriteTo(this IMetadataFormatter formatter, IResponseFormatter response)
		{
			var format = response.Context.GetResponseFormat();

			if (format == ResponseFormat.Html)
			{
				return HttpStatusCode.NoContent;
			}

			var representation = format == ResponseFormat.Json ? "json" : "xml";
			var encodedString = formatter.GetRepresentation(representation);
			var stream = new MemoryStream(Encoding.UTF8.GetBytes(encodedString));
			return response.FromStream(stream, Euclid.Common.Extensions.MimeTypes.GetByExtension(representation));
		}
Ejemplo n.º 4
0
        public static Response AsAttachment(
            this IResponseFormatter formatter,
            Stream stream,
            string attachmentName,
            string contentType = "application/text")
        {
            Require.ArgumentNotNull(formatter, nameof(formatter));
            Require.ArgumentNotNullEmpty(attachmentName, nameof(attachmentName));
            Require.ArgumentNotNullEmpty(contentType, nameof(contentType));

            var response = formatter.FromStream(stream, contentType);

            response.Headers.Add("Content-Disposition", $"attachment; filename={attachmentName}");
            response.Headers.Add("Cache-Control", "no-cache");
            response.StatusCode = HttpStatusCode.OK;
            return(response);
        }
Ejemplo n.º 5
0
        public static Response GetPageImage(Guid id, int page, int width, int height, IResponseFormatter response)
        {
            // Restrict access to the FreeImage library to one thread at a time.
            lock (lockThis)
            {
                int  max_width  = 0;
                int  max_height = 0;
                bool thumbnail  = !(width == -1 && height == -1);
                bool processed  = false;

                string filename = string.Format("{0}-p{1}-w{2}-h{3}.jpg", id, page, width, height);

                if (thumbnail)
                {
                    MemoryStream cachestream = ImageCache.Instance.LoadFromCache(filename, true, false);
                    // Cached thumbnails are assumed to be in the correct format and adhere to the size/format restrictions of the ipad.
                    if (cachestream != null)
                    {
                        return(response.FromStream(cachestream, MimeTypes.GetMimeType(".jpg")));
                    }
                }
                else
                {
                    // Check if a processed (rescaled and/or progressive) image is cached.
                    string       processed_filename = string.Format("{0}-p{1}-processed.jpg", id, page);
                    MemoryStream cachestream        = ImageCache.Instance.LoadFromCache(processed_filename, false, false);
                    if (cachestream != null)
                    {
                        return(response.FromStream(cachestream, MimeTypes.GetMimeType(".jpg")));
                    }
                }

                MemoryStream stream = null;

                // Check if original image is in the cache.
                string org_filename = string.Format("{0}-p{1}.jpg", id, page);
                stream = ImageCache.Instance.LoadFromCache(org_filename, false, false);

                if (stream == null)
                {
                    // Image is not in the cache, get it via ComicRack.
                    var bytes = GetPageImageBytes(id, page);
                    if (bytes == null)
                    {
                        return(HttpStatusCode.NotFound);
                    }

                    stream = new MemoryStream(bytes);

                    // Always save the original page to the cache
                    ImageCache.Instance.SaveToCache(org_filename, stream, false, false);
                }

                stream.Seek(0, SeekOrigin.Begin);

                Bitmap bitmap        = new Bitmap(stream, false);
                int    bitmap_width  = (int)bitmap.Width;
                int    bitmap_height = (int)bitmap.Height;
                if (ImageCache.Instance.use_max_dimension)
                {
                    int mw, mh;

                    if (bitmap_width >= bitmap_height)
                    {
                        mw = ImageCache.Instance.max_dimension_long;
                        mh = ImageCache.Instance.max_dimension_short;
                    }
                    else
                    {
                        mw = ImageCache.Instance.max_dimension_short;
                        mh = ImageCache.Instance.max_dimension_long;
                    }

                    if (bitmap_width > mw || bitmap_height > mh)
                    {
                        double scaleW = (double)mw / (double)bitmap_width;
                        double scaleH = (double)mh / (double)bitmap_height;
                        double scale  = Math.Min(scaleW, scaleH);

                        max_width  = (int)Math.Floor(scale * bitmap_width);
                        max_height = (int)Math.Floor(scale * bitmap_height);
                    }
                    else
                    {
                        max_width  = bitmap_width;
                        max_height = bitmap_height;
                    }
                }
                else
                // Check if the image dimensions exceeds the maximum image dimensions
                if ((bitmap_width * bitmap_height) > ImageCache.Instance.maximum_imagesize)
                {
                    max_width  = (int)Math.Floor(Math.Sqrt((double)bitmap_width / (double)bitmap_height * (double)ImageCache.Instance.maximum_imagesize));
                    max_height = (int)Math.Floor((double)max_width * (double)bitmap_height / (double)bitmap_width);
                }
                else
                {
                    max_width  = bitmap_width;
                    max_height = bitmap_height;
                }

                // Calculate the dimensions of the returned image.
                int result_width  = width;
                int result_height = height;

                if (result_width == -1 && result_height == -1)
                {
                    result_width  = max_width;
                    result_height = max_height;
                }
                else
                {
                    if (result_width == -1)
                    {
                        result_height = Math.Min(max_height, result_height);
                        double ratio = (double)result_height / (double)max_height;
                        result_width = (int)Math.Floor(((double)max_width * ratio));
                    }
                    else
                    if (result_height == -1)
                    {
                        result_width = Math.Min(max_width, result_width);
                        double ratio = (double)result_width / (double)max_width;
                        result_height = (int)Math.Floor(((double)max_height * ratio));
                    }
                }

                // TODO: do this per requesting target device instead of using one global setting.

                // Resize ?
                if (result_width != bitmap_width || result_height != bitmap_height)
                {
                    processed = true;
                    Bitmap resizedBitmap = Resize(bitmap, result_width, result_height);
                    bitmap.Dispose();
                    bitmap        = resizedBitmap;
                    resizedBitmap = null;
                }


                // Check if the image must be converted to progressive jpeg(Not using this)
                if (ImageCache.Instance.use_progressive_jpeg && (result_width * result_height) >= ImageCache.Instance.progressive_jpeg_size_threshold)
                {
                    processed = true;

                    // Convert image to progressive jpeg

                    // FreeImage source code reveals that lower 7 bits of the FREE_IMAGE_SAVE_FLAGS enum are used for low-level quality control.
                    // FREE_IMAGE_SAVE_FLAGS quality = (FREE_IMAGE_SAVE_FLAGS)ImageCache.Instance.progressive_jpeg_quality;
                    //FREE_IMAGE_SAVE_FLAGS flags = FREE_IMAGE_SAVE_FLAGS.JPEG_SUBSAMPLING_444 | FREE_IMAGE_SAVE_FLAGS.JPEG_PROGRESSIVE | quality;

                    //FIBITMAP dib = FreeImage.CreateFromBitmap(bitmap);
                    //bitmap.Dispose();
                    //bitmap = null;
                    //stream.Dispose();
                    stream = new MemoryStream();
                    bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
                    bitmap = null;
                    //FreeImage.SaveToStream(dib, stream, FREE_IMAGE_FORMAT.FIF_JPEG, flags);
                    //FreeImage.Unload(dib);
                    // dib.SetNull();
                }
                else
                if (processed)
                {
                    // image was rescaled, make new stream with rescaled bitmap
                    stream = GetBytesFromImage(bitmap);
                    // For now, images that were resized because they exceeded the maximum dimensions are not saved to the cache.
                }

                if (bitmap != null)
                {
                    bitmap.Dispose();
                    bitmap = null;
                }
                // Always save thumbnails to the cache
                if (thumbnail)
                {
                    ImageCache.Instance.SaveToCache(filename, stream, true, false);
                }
                else
                if (processed)
                {
                    // Store rescaled and/or progressive jpegs in the cache for now.
                    string processed_filename = string.Format("{0}-p{1}-processed.jpg", id, page);
                    ImageCache.Instance.SaveToCache(processed_filename, stream, false, false);
                }

                stream.Seek(0, SeekOrigin.Begin);
                return(response.FromStream(stream, MimeTypes.GetMimeType(".jpg")));
            }
        }
Ejemplo n.º 6
0
 public static Response GetIcon(string key, IResponseFormatter response)
 {
     var image = ComicBook.PublisherIcons.GetImage(key);
     if (image == null)
     {
         return response.AsRedirect("/original/Views/spacer.png");
     }
     return response.FromStream(GetBytesFromImage(image), MimeTypes.GetMimeType(".jpg"));
 }
Ejemplo n.º 7
0
        public static Response GetPageImage(Guid id, int page, int width, int height, IResponseFormatter response)
        {
          // Restrict access to the FreeImage library to one thread at a time.
          lock(lockThis)
          {
            int max_width = 0;
            int max_height = 0;
            bool thumbnail = !(width == -1 && height == -1);
            bool processed = false;
            
            string filename = string.Format("{0}-p{1}-w{2}-h{3}.jpg", id, page, width, height);
            
            if (thumbnail)
            {
              MemoryStream cachestream = ImageCache.Instance.LoadFromCache(filename, true);
              // Cached thumbnails are assumed to be in the correct format and adhere to the size/format restrictions of the ipad.
              if (cachestream != null)
                return response.FromStream(cachestream, MimeTypes.GetMimeType(".jpg"));
            }
            else
            {
              // Check if a processed (rescaled and/or progressive) image is cached.
              string processed_filename = string.Format("{0}-p{1}-processed.jpg", id, page);
              MemoryStream cachestream = ImageCache.Instance.LoadFromCache(processed_filename, false);
              if (cachestream != null)
                return response.FromStream(cachestream, MimeTypes.GetMimeType(".jpg"));
            }

            MemoryStream stream = null;
            
            // Check if original image is in the cache.
            string org_filename = string.Format("{0}-p{1}.jpg", id, page);
            stream = ImageCache.Instance.LoadFromCache(org_filename, false);
              
            if (stream == null)
            {
              // Image is not in the cache, get it via ComicRack.
              var bytes = GetPageImageBytes(id, page);
              if (bytes == null)
              {
                return HttpStatusCode.NotFound;
              }
                
              stream = new MemoryStream(bytes);
                
              // Always save the original page to the cache
              ImageCache.Instance.SaveToCache(org_filename, stream, false);
            }
                        
            stream.Seek(0, SeekOrigin.Begin);

            #if USE_GDI
            
              Bitmap bitmap = new Bitmap(stream, false);
              int bitmap_width = (int)bitmap.Width;
              int bitmap_height = (int)bitmap.Height;
              
            #elif USE_DIB
            
              FIBITMAP dib = FreeImage.LoadFromStream(stream);
              if (dib == null)
              {
                Console.WriteLine("Loading bitmap failed. Aborting.");
                // Check whether there was an error message.
                return HttpStatusCode.InternalServerError;
              }
              int bitmap_width = (int)FreeImage.GetWidth(dib);
              int bitmap_height = (int)FreeImage.GetHeight(dib);
            
            #elif USE_FIB
            
              FreeImageBitmap fib = FreeImageBitmap.FromStream(stream, false);
              if (fib == null)
              {
                Console.WriteLine("Loading bitmap failed. Aborting.");
                // Check whether there was an error message.
                return HttpStatusCode.InternalServerError;
              }
                                      
              int bitmap_width = (int)fib.Width;
              int bitmap_height = (int)fib.Height;
            #endif
            
            if (ImageCache.Instance.use_max_dimension)
            {
              int mw, mh;
              
              if (bitmap_width >= bitmap_height)
              {
                mw = ImageCache.Instance.max_dimension_long;
                mh = ImageCache.Instance.max_dimension_short;
              }
              else
              {
                mw = ImageCache.Instance.max_dimension_short;
                mh = ImageCache.Instance.max_dimension_long;
              }
              
              if (bitmap_width > mw || bitmap_height > mh)
              {
                double scaleW = (double)mw / (double)bitmap_width;
                double scaleH = (double)mh / (double)bitmap_height;
                double scale = Math.Min(scaleW, scaleH);
                
                max_width = (int)Math.Floor(scale * bitmap_width);
                max_height = (int)Math.Floor(scale * bitmap_height);
              }
              else
              {
                max_width = bitmap_width;
                max_height = bitmap_height;
              }
            }
            else            
            // Check if the image dimensions exceeds the maximum image dimensions
            if ((bitmap_width * bitmap_height) > ImageCache.Instance.maximum_imagesize)
            {
              max_width = (int)Math.Floor(Math.Sqrt((double)bitmap_width / (double)bitmap_height * (double)ImageCache.Instance.maximum_imagesize));
              max_height = (int)Math.Floor((double)max_width * (double)bitmap_height / (double)bitmap_width);
            }
            else
            {
              max_width = bitmap_width;
              max_height = bitmap_height;
            }
                        
            // Calculate the dimensions of the returned image.
            int result_width = width;
            int result_height = height;
            
            if (result_width == -1 && result_height == -1)
            {
              result_width = max_width;
              result_height = max_height;
            }
            else
            {
              if (result_width == -1)
              {
                result_height = Math.Min(max_height, result_height);
                double ratio = (double)result_height / (double)max_height;
                result_width = (int)Math.Floor(((double)max_width * ratio));
              }
              else
              if (result_height == -1)
              {
                result_width = Math.Min(max_width, result_width);
                double ratio = (double)result_width / (double)max_width;
                result_height = (int)Math.Floor(((double)max_height * ratio));
              }
            }
            
            // TODO: do this per requesting target device instead of using one global setting.
            
            // Resize ?
            if (result_width != bitmap_width || result_height != bitmap_height)
            {
                processed = true;
                
              #if USE_DIB || USE_FIB
                //FREE_IMAGE_FILTER resizer = FREE_IMAGE_FILTER.FILTER_BICUBIC;
                FREE_IMAGE_FILTER resizer = FREE_IMAGE_FILTER.FILTER_LANCZOS3;
                
                #if USE_FIB
                  fib.Rescale(result_width, result_height, resizer);
                #else
                              
                  FIBITMAP newdib = FreeImage.Rescale(dib, result_width, result_height, resizer);
                  if (!newdib.IsNull)
                  {
                    FreeImage.Unload(dib);
                    dib.SetNull();
                    dib = newdib;
                  }
                #endif
              #elif USE_GDI
                Bitmap resizedBitmap = Resize(bitmap, result_width, result_height);
                bitmap.Dispose();
                bitmap = resizedBitmap;
                resizedBitmap = null;
              #endif
            }
            
            
            // Check if the image must be converted to progressive jpeg
            if (ImageCache.Instance.use_progressive_jpeg && (result_width * result_height) >= ImageCache.Instance.progressive_jpeg_size_threshold)
            {
              processed = true;
              
              // Convert image to progressive jpeg
              
              // FreeImage source code reveals that lower 7 bits of the FREE_IMAGE_SAVE_FLAGS enum are used for low-level quality control.
              FREE_IMAGE_SAVE_FLAGS quality = (FREE_IMAGE_SAVE_FLAGS)ImageCache.Instance.progressive_jpeg_quality;
              FREE_IMAGE_SAVE_FLAGS flags = FREE_IMAGE_SAVE_FLAGS.JPEG_SUBSAMPLING_444 | FREE_IMAGE_SAVE_FLAGS.JPEG_PROGRESSIVE | quality;

              #if USE_DIB || USE_FIB
                
                stream.Dispose();
                stream = new MemoryStream();
                
                #if USE_FIB
                
                  fib.Save(stream, FREE_IMAGE_FORMAT.FIF_JPEG, flags);
                  fib.Dispose();
                  
                #else
                
                  FreeImage.SaveToStream(dib, stream, FREE_IMAGE_FORMAT.FIF_JPEG, flags);
                  FreeImage.Unload(dib);
                  dib.SetNull();
                 
                #endif
                
              #else
                FIBITMAP dib = FreeImage.CreateFromBitmap(bitmap);
                bitmap.Dispose();
                bitmap = null;
                stream.Dispose();
                stream = new MemoryStream();
                
                FreeImage.SaveToStream(dib, stream, FREE_IMAGE_FORMAT.FIF_JPEG, flags);
                FreeImage.Unload(dib);
                dib.SetNull();
                
              #endif              
            }
            else
            if (processed) 
            {
              // image was rescaled, make new stream with rescaled bitmap
              
              #if USE_DIB || USE_FIB
              
                FREE_IMAGE_SAVE_FLAGS flags = FREE_IMAGE_SAVE_FLAGS.JPEG_SUBSAMPLING_444 | FREE_IMAGE_SAVE_FLAGS.JPEG_OPTIMIZE | FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYNORMAL;
                
                stream.Dispose();  
                stream = new MemoryStream();
                
                #if USE_FIB
                  fib.Save(stream, FREE_IMAGE_FORMAT.FIF_JPEG, flags);
                  fib.Dispose();
                #else
                  FreeImage.SaveToStream(dib, stream, FREE_IMAGE_FORMAT.FIF_JPEG, flags);
                  FreeImage.Unload(dib);
                  dib.SetNull();
                #endif
              #else
              
                stream = GetBytesFromImage(bitmap);
   
              #endif           
              // For now, images that were resized because they exceeded the maximum dimensions are not saved to the cache.
            }
            
            #if USE_DIB
              FreeImage.Unload(dib);
              dib.SetNull();
            #elif USE_FIB
              fib.Dispose();
            #elif USE_GDI

            if (bitmap != null)
            {
              bitmap.Dispose();
              bitmap = null;
            }

            #endif
            
            // Always save thumbnails to the cache
            if (thumbnail)
            {
              ImageCache.Instance.SaveToCache(filename, stream, true);
            }
            else
            if (processed)
            {
              // Store rescaled and/or progressive jpegs in the cache for now.
              string processed_filename = string.Format("{0}-p{1}-processed.jpg", id, page);
              ImageCache.Instance.SaveToCache(processed_filename, stream, false);
            }
            
            stream.Seek(0, SeekOrigin.Begin);
            return response.FromStream(stream, MimeTypes.GetMimeType(".jpg"));
          }
        }
Ejemplo n.º 8
0
 public static Response GetThumbnailImage(Guid id, int page, IResponseFormatter response)
 {
     var bitmap = Image.FromStream(new MemoryStream(GetPageImageBytes(id, page)), false, false);
     double ratio = 200D / (double)bitmap.Height;
     int width = (int)(bitmap.Width * ratio);
     var callback = new Image.GetThumbnailImageAbort(() => true);
     var thumbnail = bitmap.GetThumbnailImage(width, 200, callback, IntPtr.Zero);
     MemoryStream stream = GetBytesFromImage(thumbnail);
     return response.FromStream(stream, MimeTypes.GetMimeType(".jpg"));
 }
Ejemplo n.º 9
0
 public static Response GetPageImage(Guid id, int page, IResponseFormatter response)
 {
     var bytes = GetPageImageBytes(id, page);
     if (bytes == null)
     {
         return response.AsRedirect("/Comics/Images/spacer.png");
     }
     return response.FromStream(new MemoryStream(bytes), MimeTypes.GetMimeType(".jpg"));
 }