Esempio n. 1
0
        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
        {
            _context = context;

            ImageRequestState state = new ImageRequestState();

            string quality = "";
            string format  = "png";
            int    dotPos  = context.Request["quality_format"].IndexOf(".");

            if (dotPos != -1)
            {
                quality = context.Request["quality_format"].Substring(0, dotPos);
                format  = context.Request["quality_format"].Substring(dotPos + 1);
            }
            else
            {
                quality = context.Request["quality_format"];
            }

            if (string.IsNullOrEmpty(context.Request["identifier"]) || string.IsNullOrEmpty(context.Request["size"]) ||
                string.IsNullOrEmpty(context.Request["region"]) || string.IsNullOrEmpty(quality) ||
                string.IsNullOrEmpty(context.Request["rotation"]))
            {
                state.err = new error();

                if (string.IsNullOrEmpty(context.Request["identifier"]))
                {
                    state.err.parameter = ", identifier";
                }
                if (string.IsNullOrEmpty(context.Request["size"]))
                {
                    state.err.parameter += ", size";
                }
                if (string.IsNullOrEmpty(context.Request["region"]))
                {
                    state.err.parameter += ", region";
                }
                if (string.IsNullOrEmpty(context.Request["rotation"]))
                {
                    state.err.parameter += ", rotation";
                }
                if (string.IsNullOrEmpty(quality))
                {
                    state.err.parameter += ", quality";
                }
                if (string.IsNullOrEmpty(context.Request["format"]))
                {
                    state.err.parameter += ", format";
                }

                state.err.parameter = state.err.parameter.Substring(2);
                state.err.text      = "missing " + state.err.parameter;

                state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
            }

            string size = context.Request["size"];

            if (state.err == null && !string.IsNullOrEmpty(size))
            {
                if (size.EndsWith(","))
                {
                    state.sizeType = "resize";
                    state.width    = size.Replace(",", "");

                    if (!string.IsNullOrEmpty(state.width) && int.Parse(state.width) < 1)
                    {
                        state.err            = new error();
                        state.err.parameter  = "size";
                        state.err.text       = "Invalid size specified";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                }
                else if (size.StartsWith(","))
                {
                    state.sizeType = "resize";
                    state.height   = size.Replace(",", "");

                    if (!string.IsNullOrEmpty(state.height) && int.Parse(state.height) < 1)
                    {
                        state.err            = new error();
                        state.err.parameter  = "size";
                        state.err.text       = "Invalid size specified";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                }
                else if (size.Equals("full"))
                {
                    state.sizeType = "proportion";
                    state.size     = "1";
                }
                else if (size.StartsWith("pct:"))
                {
                    state.sizeType = "proportion";
                    state.size     = (double.Parse(size.Replace("pct:", "")) / 100).ToString();

                    if (!string.IsNullOrEmpty(state.size) && double.Parse(state.size) <= 0)
                    {
                        state.err            = new error();
                        state.err.parameter  = "size";
                        state.err.text       = "Invalid size specified";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                }
                else if (size.StartsWith("!"))
                {
                    Regex r = new Regex(@"!(?<w>\d+),(?<h>\d+)");
                    Match m = r.Match(size);

                    state.sizeType = "best";
                    state.width    = m.Groups["w"].Value;
                    state.height   = m.Groups["h"].Value;

                    if ((!string.IsNullOrEmpty(state.width) && int.Parse(state.width) < 1) ||
                        (!string.IsNullOrEmpty(state.height) && int.Parse(state.height) < 1))
                    {
                        state.err            = new error();
                        state.err.parameter  = "size";
                        state.err.text       = "Invalid size specified";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                }
                else
                {
                    Regex r = new Regex(@"(?<w>\d+),(?<h>\d+)");
                    Match m = r.Match(size);

                    state.sizeType = "resize";
                    state.width    = m.Groups["w"].Value;
                    state.height   = m.Groups["h"].Value;

                    if ((!string.IsNullOrEmpty(state.width) && int.Parse(state.width) < 1) ||
                        (!string.IsNullOrEmpty(state.height) && int.Parse(state.height) < 1))
                    {
                        state.err            = new error();
                        state.err.parameter  = "size";
                        state.err.text       = "Invalid size specified";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                }

                if (string.IsNullOrEmpty(state.sizeType) || (string.IsNullOrEmpty(state.size) && string.IsNullOrEmpty(state.height) && string.IsNullOrEmpty(state.width)))
                {
                    state.err            = new error();
                    state.err.parameter  = "size";
                    state.err.text       = "Invalid size specified";
                    state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                }
            }

            string region = context.Request["region"];

            if (state.err == null && !string.IsNullOrEmpty(region))
            {
                if (context.Request["region"].Equals("full"))
                {
                    state.region = "all";
                }
                else if (region.StartsWith("pct:"))
                {
                    Regex  r = new Regex(@"pct:(?<x>(\d+|\d+\.\d+)),(?<y>(\d+|\d+\.\d+)),(?<w>(\d+|\d+\.\d+)),(?<h>(\d+|\d+\.\d+))");
                    Match  m = r.Match(region);
                    double y = Convert.ToDouble(m.Groups["y"].Value) / 100;
                    double x = Convert.ToDouble(m.Groups["x"].Value) / 100;
                    double h = Convert.ToDouble(m.Groups["h"].Value) / 100;
                    double w = Convert.ToDouble(m.Groups["w"].Value) / 100;

                    state.region = "%" + x + "," + y + "," + w + "," + h;

                    state.regionHeight = h.ToString();
                    state.regionWidth  = w.ToString();

                    if ((!string.IsNullOrEmpty(state.regionWidth) && Convert.ToDouble(state.regionWidth) <= 0) ||
                        (!string.IsNullOrEmpty(state.regionHeight) && Convert.ToDouble(state.regionHeight) <= 0))
                    {
                        state.err            = new error();
                        state.err.parameter  = "region";
                        state.err.text       = "Invalid region specified";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                }
                else
                {
                    Regex r = new Regex(@"(?<x>\d+),(?<y>\d+),(?<w>\d+),(?<h>\d+)");
                    Match m = r.Match(region);

                    state.region       = m.Groups["x"].Value + "," + m.Groups["y"].Value + "," + m.Groups["w"].Value + "," + m.Groups["h"].Value;
                    state.regionHeight = m.Groups["h"].Value;
                    state.regionWidth  = m.Groups["w"].Value;

                    if (state.sizeType.Equals("proportion"))
                    {
                        if (!string.IsNullOrEmpty(state.regionWidth) && Convert.ToInt32(state.regionWidth) * Convert.ToDouble(state.size) < 1)
                        {
                            state.err            = new error();
                            state.err.parameter  = "region";
                            state.err.text       = "Invalid region specified";
                            state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                        }
                        else if (!string.IsNullOrEmpty(state.regionHeight) && Convert.ToInt32(state.regionHeight) * Convert.ToDouble(state.size) < 1)
                        {
                            state.err            = new error();
                            state.err.parameter  = "region";
                            state.err.text       = "Invalid region specified";
                            state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                        }
                    }
                    if ((!string.IsNullOrEmpty(state.regionWidth) && int.Parse(state.regionWidth) < 1) ||
                        (!string.IsNullOrEmpty(state.regionHeight) && int.Parse(state.regionHeight) < 1))
                    {
                        state.err            = new error();
                        state.err.parameter  = "region";
                        state.err.text       = "Invalid region specified";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                }

                if (string.IsNullOrEmpty(state.region.Replace(",", "")))
                {
                    state.err            = new error();
                    state.err.parameter  = "region";
                    state.err.text       = "Invalid region specified";
                    state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                }
            }

            if (state.err == null && !string.IsNullOrEmpty(quality))
            {
                switch (quality)
                {
                case "grey": quality = "grey"; break;

                case "bitonal": quality = "bitonal"; break;

                case "color": quality = "color"; break;

                case "native": quality = "native"; break;

                default:
                    state.err            = new error();
                    state.err.parameter  = "quality";
                    state.err.text       = "only native, color, grey, bitonal supported";
                    state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    break;
                }
            }

            string rotate = context.Request["rotation"];

            if (state.err == null && !string.IsNullOrEmpty(rotate))
            {
                switch (rotate)
                {
                case "90":
                case "180":
                case "270":
                    state.rotation = rotate; break;

                default:
                    int temp = 0;
                    if (int.TryParse(rotate, out temp))
                    {
                        state.rotation = temp.ToString();
                    }
                    else
                    {
                        state.err            = new error();
                        state.err.parameter  = "rotation";
                        state.err.text       = "only 0, 90, 180, 270 are accepted rotation values";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                    break;
                }
            }

            if (state.err == null && !string.IsNullOrEmpty(format))
            {
                switch (format)
                {
                case "jpg": format = "jpg"; break;

                case "png": format = "png"; break;

                case "gif": format = "gif"; break;

                case "jp2":
                case "pdf":
                default:
                    state.err            = new error();
                    state.err.parameter  = "format";
                    state.err.text       = format + " not supported";
                    state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    break;         // no format matched
                }
            }

            state.identifier = context.Request["identifier"];
            state.rotation   = context.Request["rotation"];
            state.quality    = quality;
            state.format     = format;

            asynch = new ImageAsynchResult(cb, context, state);

            getImage = new GetImageDelegate(GetImage);
            getImage.BeginInvoke(asynch, null, state);

            return(asynch);
        }
Esempio n. 2
0
        public void EndProcessRequest(IAsyncResult result)
        {
            _context.Response.AddHeader("Link", "<http://library.stanford.edu/iiif/image-api/compliance.html#level2>;rel=\"profile\"");
            if (_ex != null)
            {
                // If an exception was thrown, rethrow it
                throw _ex;
            }
            else
            {
                ImageRequestState state = (ImageRequestState)result.AsyncState;
                if (state.err != null)
                {
                    string xmlError            = "";
                    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                    ns.Add("", "http://library.stanford.edu/iiif/image-api/ns/");

                    XmlSerializer xs = new XmlSerializer(state.err.GetType());
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        XmlWriterSettings settings = new XmlWriterSettings()
                        {
//                            Encoding = Encoding.ASCII
                            Encoding = new UTF8Encoding(false)
                        };
                        using (XmlWriter writer = XmlWriter.Create(memoryStream, settings))
                        {
                            xs.Serialize(writer, state.err, ns);
                        }
                        xmlError = Encoding.UTF8.GetString(memoryStream.ToArray());
//                        xmlError = Encoding.ASCII.GetString(memoryStream.ToArray());
                    }

                    _context.Response.StatusCode             = (int)state.err.statusCode;
                    _context.Response.TrySkipIisCustomErrors = true;
                    _context.Response.ContentType            = "application/xml";
                    _context.Response.Charset = "";
                    _context.Response.Write(xmlError);
                }
                else
                {
                    string      contentType = "image/png";
                    ImageFormat imageFormat = ImageFormat.Png;

                    switch (state.format)
                    {
                    case "jpg": imageFormat = ImageFormat.Jpeg; contentType = "image/jpeg"; break;

                    case "gif": imageFormat = ImageFormat.Gif; contentType = "image/gif"; break;
                    }

                    _context.Response.ContentType = contentType;

                    if (state.quality.Equals("native"))
                    {
                        _bitmap.Save(_context.Response.OutputStream, imageFormat);
                    }
                    else
                    {
                        ImageCodecInfo codec = GetEncoderInfo(contentType);

                        System.Drawing.Imaging.Encoder encoder = System.Drawing.Imaging.Encoder.ColorDepth;
                        EncoderParameters encoderParameters    = new EncoderParameters(1);
                        if (state.quality.Equals("color"))
                        {
                            encoderParameters.Param[0] = new EncoderParameter(encoder, 24L);
                        }
                        else if (state.quality.Equals("grey"))
                        {
                            encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 8);

                            _bitmap = CopyToBpp(_bitmap, 8);
                        }
                        else    // must be bitonal
                        {
                            encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 1);

                            _bitmap = CopyToBpp(_bitmap, 1);
                        }
                        _bitmap.Save(_context.Response.OutputStream, codec, encoderParameters);
                    }
                    _bitmap.Dispose();
                }
            }
        }
Esempio n. 3
0
        private void GetImage(IAsyncResult p_res)
        {
            ImageRequestState state = (ImageRequestState)p_res.AsyncState;

            if (state.err != null)
            {
                asynch.CompleteCall();
            }
            else
            {
                lock (lockobj)
                {
                    try
                    {
                        Extractor kdu       = new Extractor();
                        State     kdu_state = new State();

                        kdu_state.File     = state.identifier.EndsWith(".jp2") ? state.identifier : state.identifier + ".jp2";
                        kdu_state.SizeType = state.sizeType;
                        kdu_state.Size     = string.IsNullOrEmpty(state.size) ? 0 : float.Parse(state.size);
                        kdu_state.Width    = string.IsNullOrEmpty(state.width) ? 0 : int.Parse(state.width);
                        kdu_state.Height   = string.IsNullOrEmpty(state.height) ? 0 : int.Parse(state.height);
                        kdu_state.Region   = state.region;
                        kdu_state.Format   = state.format;
                        kdu_state.Quality  = state.quality;

                        Stream stream = kdu.GetImage(kdu_state);
                        Image  img    = Image.FromStream(stream);

                        if (state.sizeType.Equals("resize"))
                        {
                            int sizeWidth  = img.Width;
                            int sizeHeight = img.Height;

                            if (!string.IsNullOrEmpty(state.width) && !string.IsNullOrEmpty(state.height))
                            {
                                sizeWidth  = Convert.ToInt32(state.width);
                                sizeHeight = Convert.ToInt32(state.height);
                            }
                            else if (!string.IsNullOrEmpty(state.width))
                            {
                                sizeWidth  = Convert.ToInt32(state.width);
                                sizeHeight = (int)(((float)sizeWidth / img.Width) * sizeHeight);
                            }
                            else if (!string.IsNullOrEmpty(state.height))
                            {
                                sizeHeight = Convert.ToInt32(state.height);
                                sizeWidth  = (int)(((float)sizeHeight / img.Height) * sizeWidth);
                            }

                            img = ResizeImage(img, sizeWidth, sizeHeight);
                        }
                        else if (state.sizeType.Equals("best"))
                        {
                            int    sizeWidth   = Convert.ToInt32(state.width);
                            int    sizeHeight  = Convert.ToInt32(state.height);
                            double regionWidth = img.Width;
                            if (!string.IsNullOrEmpty(state.regionWidth))
                            {
                                regionWidth = Convert.ToDouble(state.regionWidth);
                            }
                            double regionHeight = img.Height;
                            if (!string.IsNullOrEmpty(state.regionHeight))
                            {
                                regionHeight = Convert.ToDouble(state.regionHeight);
                            }

                            double scalex = sizeWidth / regionWidth;
                            double scaley = sizeHeight / regionHeight;

                            if (scalex < scaley)
                            {
                                img = ResizeImage(img, (int)(regionWidth * scalex), (int)(regionHeight * scalex));
                            }
                            else
                            {
                                img = ResizeImage(img, (int)(regionWidth * scaley), (int)(regionHeight * scaley));
                            }
                        }
                        else if (state.sizeType.Equals("proportion"))
                        {
                            double regionWidth  = 0;
                            double regionHeight = 0;

                            if (state.region.Equals("all"))
                            {
                                XmlDocument doc = new XmlDocument();
                                doc.LoadXml(kdu.GetMetadata(state.identifier.EndsWith(".jp2") ? state.identifier : state.identifier + ".jp2"));

                                regionWidth  = Convert.ToInt32(doc.GetElementsByTagName("Width")[0].InnerText);
                                regionHeight = Convert.ToInt32(doc.GetElementsByTagName("Height")[0].InnerText);
                            }
                            else if (state.region.StartsWith("%"))
                            {
                                XmlDocument doc = new XmlDocument();
                                doc.LoadXml(kdu.GetMetadata(state.identifier.EndsWith(".jp2") ? state.identifier : state.identifier + ".jp2"));

                                regionWidth  = Convert.ToDouble(state.regionWidth) * Convert.ToInt32(doc.GetElementsByTagName("Width")[0].InnerText);
                                regionHeight = Convert.ToDouble(state.regionHeight) * Convert.ToInt32(doc.GetElementsByTagName("Height")[0].InnerText);
                            }
                            else
                            {
                                regionWidth  = Convert.ToInt32(state.regionWidth);
                                regionHeight = Convert.ToInt32(state.regionHeight);
                            }

                            regionWidth  *= Convert.ToDouble(state.size);
                            regionHeight *= Convert.ToDouble(state.size);

                            if (regionWidth < 1 || regionHeight < 1)
                            {
                                state.err            = new error();
                                state.err.parameter  = "region / size";
                                state.err.text       = "Invalid region /size specified";
                                state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                            }
                            else
                            {
                                img = ResizeImage(img, (int)regionWidth, (int)regionHeight);
                            }
                        }

                        if (state.err == null)
                        {
                            if (!string.IsNullOrEmpty(state.quality))
                            {
                                if (state.quality.Equals("grey"))
                                {
                                    img = MakeGrayscale(new Bitmap(img));
                                }
                                else if (state.quality.Equals("bitonal"))
                                {
                                    img = MakeBitonal(new Bitmap(img));
                                }
                            }

                            switch (state.rotation)
                            {
                            case "90": img.RotateFlip(RotateFlipType.Rotate90FlipNone); break;

                            case "180": img.RotateFlip(RotateFlipType.Rotate180FlipNone); break;

                            case "270": img.RotateFlip(RotateFlipType.Rotate270FlipNone); break;
                            }

                            _bitmap = new Bitmap(img);
                        }
                    }
                    catch (IIIFException e)
                    {
                        state.err = new error();

                        try
                        {
                            XmlDocument doc = new XmlDocument();
                            doc.LoadXml(e.Message);

                            if (doc.GetElementsByTagName("Code")[0].InnerText.Contains("i3f_200"))
                            {
                                state.err.parameter  = "identifier";
                                state.err.text       = doc.GetElementsByTagName("Message")[0].InnerText;
                                state.err.statusCode = System.Net.HttpStatusCode.NotFound;
                            }
                            else if (doc.GetElementsByTagName("Code")[0].InnerText.Contains("i3f_400"))
                            {
                                state.err.parameter  = "region";
                                state.err.text       = doc.GetElementsByTagName("Message")[0].InnerText;
                                state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                            }
                            else
                            {
                                state.err.parameter  = "unknown";
                                state.err.text       = e.Message;
                                state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                            }
                        }
                        catch (Exception ex)
                        {
                            state.err.parameter  = "unknown";
                            state.err.text       = ex.Message;
                            state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                        }
                    }
                    catch (Exception e)
                    {
                        state.err            = new error();
                        state.err.parameter  = "unknown";
                        state.err.text       = e.Message;
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                    finally
                    {
                        asynch.CompleteCall();
                    }
                }
            }
        }
        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
        {
            _context = context;

            ImageRequestState state = new ImageRequestState();

            string quality = "";
            string format = "png";
            int dotPos = context.Request["quality_format"].IndexOf(".");

            if (dotPos != -1)
            {
                quality = context.Request["quality_format"].Substring(0, dotPos);
                format = context.Request["quality_format"].Substring(dotPos + 1);
            }
            else
            {
                quality = context.Request["quality_format"];
            }

            if (string.IsNullOrEmpty(context.Request["identifier"]) || string.IsNullOrEmpty(context.Request["size"]) ||
                string.IsNullOrEmpty(context.Request["region"]) || string.IsNullOrEmpty(quality) ||
                string.IsNullOrEmpty(context.Request["rotation"]))
            {
                state.err = new error();

                if (string.IsNullOrEmpty(context.Request["identifier"]))
                    state.err.parameter = ", identifier";
                if (string.IsNullOrEmpty(context.Request["size"]))
                    state.err.parameter += ", size";
                if (string.IsNullOrEmpty(context.Request["region"]))
                    state.err.parameter += ", region";
                if (string.IsNullOrEmpty(context.Request["rotation"]))
                    state.err.parameter += ", rotation";
                if (string.IsNullOrEmpty(quality))
                    state.err.parameter += ", quality";
                if (string.IsNullOrEmpty(context.Request["format"]))
                    state.err.parameter += ", format";

                state.err.parameter = state.err.parameter.Substring(2);
                state.err.text = "missing " + state.err.parameter;

                state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
            }

            string size = context.Request["size"];
            if (state.err == null && !string.IsNullOrEmpty(size))
            {
                if (size.EndsWith(","))
                {
                    state.sizeType = "resize";
                    state.width = size.Replace(",", "");

                    if (!string.IsNullOrEmpty(state.width) && int.Parse(state.width) < 1)
                    {
                        state.err = new error();
                        state.err.parameter = "size";
                        state.err.text = "Invalid size specified";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                }
                else if (size.StartsWith(","))
                {
                    state.sizeType = "resize";
                    state.height = size.Replace(",", "");

                    if (!string.IsNullOrEmpty(state.height) && int.Parse(state.height) < 1)
                    {
                        state.err = new error();
                        state.err.parameter = "size";
                        state.err.text = "Invalid size specified";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                }
                else if (size.Equals("full"))
                {
                    state.sizeType = "proportion";
                    state.size = "1";
                }
                else if (size.StartsWith("pct:"))
                {
                    state.sizeType = "proportion";
                    state.size = (double.Parse(size.Replace("pct:", "")) / 100).ToString();

                    if (!string.IsNullOrEmpty(state.size) && double.Parse(state.size) <= 0)
                    {
                        state.err = new error();
                        state.err.parameter = "size";
                        state.err.text = "Invalid size specified";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                }
                else if (size.StartsWith("!"))
                {
                    Regex r = new Regex(@"!(?<w>\d+),(?<h>\d+)");
                    Match m = r.Match(size);

                    state.sizeType = "best";
                    state.width = m.Groups["w"].Value;
                    state.height = m.Groups["h"].Value;

                    if ((!string.IsNullOrEmpty(state.width) && int.Parse(state.width) < 1) ||
                        (!string.IsNullOrEmpty(state.height) && int.Parse(state.height) < 1))
                    {
                        state.err = new error();
                        state.err.parameter = "size";
                        state.err.text = "Invalid size specified";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                }
                else
                {
                    Regex r = new Regex(@"(?<w>\d+),(?<h>\d+)");
                    Match m = r.Match(size);

                    state.sizeType = "resize";
                    state.width = m.Groups["w"].Value;
                    state.height = m.Groups["h"].Value;

                    if ((!string.IsNullOrEmpty(state.width) && int.Parse(state.width) < 1) ||
                        (!string.IsNullOrEmpty(state.height) && int.Parse(state.height) < 1))
                    {
                        state.err = new error();
                        state.err.parameter = "size";
                        state.err.text = "Invalid size specified";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                }

                if (string.IsNullOrEmpty(state.sizeType) || (string.IsNullOrEmpty(state.size) && string.IsNullOrEmpty(state.height) && string.IsNullOrEmpty(state.width)))
                {
                    state.err = new error();
                    state.err.parameter = "size";
                    state.err.text = "Invalid size specified";
                    state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                }
            }

            string region = context.Request["region"];
            if (state.err == null && !string.IsNullOrEmpty(region))
            {
                if (context.Request["region"].Equals("full"))
                {
                    state.region = "all";
                }
                else if (region.StartsWith("pct:"))
                {
                    Regex r = new Regex(@"pct:(?<x>(\d+|\d+\.\d+)),(?<y>(\d+|\d+\.\d+)),(?<w>(\d+|\d+\.\d+)),(?<h>(\d+|\d+\.\d+))");
                    Match m = r.Match(region);
                    double y = Convert.ToDouble(m.Groups["y"].Value) / 100;
                    double x = Convert.ToDouble(m.Groups["x"].Value) / 100;
                    double h = Convert.ToDouble(m.Groups["h"].Value) / 100;
                    double w = Convert.ToDouble(m.Groups["w"].Value) / 100;

                    state.region = "%" + x + "," + y + "," + w + "," + h;

                    state.regionHeight = h.ToString();
                    state.regionWidth = w.ToString();

                    if ((!string.IsNullOrEmpty(state.regionWidth) && Convert.ToDouble(state.regionWidth) <= 0) ||
                        (!string.IsNullOrEmpty(state.regionHeight) && Convert.ToDouble(state.regionHeight) <= 0))
                    {
                        state.err = new error();
                        state.err.parameter = "region";
                        state.err.text = "Invalid region specified";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                }
                else
                {
                    Regex r = new Regex(@"(?<x>\d+),(?<y>\d+),(?<w>\d+),(?<h>\d+)");
                    Match m = r.Match(region);

                    state.region = m.Groups["x"].Value + "," + m.Groups["y"].Value + "," + m.Groups["w"].Value + "," + m.Groups["h"].Value;
                    state.regionHeight = m.Groups["h"].Value;
                    state.regionWidth = m.Groups["w"].Value;

                    if (state.sizeType.Equals("proportion"))
                    {
                        if (!string.IsNullOrEmpty(state.regionWidth) && Convert.ToInt32(state.regionWidth) * Convert.ToDouble(state.size) < 1)
                        {
                            state.err = new error();
                            state.err.parameter = "region";
                            state.err.text = "Invalid region specified";
                            state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                        }
                        else if (!string.IsNullOrEmpty(state.regionHeight) && Convert.ToInt32(state.regionHeight) * Convert.ToDouble(state.size) < 1)
                        {
                            state.err = new error();
                            state.err.parameter = "region";
                            state.err.text = "Invalid region specified";
                            state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                        }
                    }
                    if ((!string.IsNullOrEmpty(state.regionWidth) && int.Parse(state.regionWidth) < 1) ||
                        (!string.IsNullOrEmpty(state.regionHeight) && int.Parse(state.regionHeight) < 1))
                    {
                        state.err = new error();
                        state.err.parameter = "region";
                        state.err.text = "Invalid region specified";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                    }
                }

                if (string.IsNullOrEmpty(state.region.Replace(",", "")))
                {
                    state.err = new error();
                    state.err.parameter = "region";
                    state.err.text = "Invalid region specified";
                    state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                }
            }

            if (state.err == null && !string.IsNullOrEmpty(quality))
            {
                switch (quality)
                {
                    case "grey": quality = "grey"; break;
                    case "bitonal": quality = "bitonal"; break;
                    case "color": quality = "color"; break;
                    case "native": quality = "native"; break;
                    default:
                        state.err = new error();
                        state.err.parameter = "quality";
                        state.err.text = "only native, color, grey, bitonal supported";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                        break;
                }
            }

            string rotate = context.Request["rotation"];
            if (state.err == null && !string.IsNullOrEmpty(rotate))
            {
                switch (rotate)
                {
                    case "90":
                    case "180":
                    case "270":
                        state.rotation = rotate; break;
                    default:
                        int temp = 0;
                        if (int.TryParse(rotate, out temp))
                        {
                            state.rotation = temp.ToString();
                        }
                        else
                        {
                            state.err = new error();
                            state.err.parameter = "rotation";
                            state.err.text = "only 0, 90, 180, 270 are accepted rotation values";
                            state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                        }
                        break;
                }

            }

            if (state.err == null && !string.IsNullOrEmpty(format))
            {
                switch (format)
                {
                    case "jpg": format = "jpg"; break;
                    case "png": format = "png"; break;
                    case "gif": format = "gif"; break;
                    case "jp2":
                    case "pdf":
                    default:
                        state.err = new error();
                        state.err.parameter = "format";
                        state.err.text = format + " not supported";
                        state.err.statusCode = System.Net.HttpStatusCode.BadRequest;
                        break;     // no format matched
                }
            }

            state.identifier = context.Request["identifier"];
            state.rotation = context.Request["rotation"];
            state.quality = quality;
            state.format = format;

            asynch = new ImageAsynchResult(cb, context, state);

            getImage = new GetImageDelegate(GetImage);
            getImage.BeginInvoke(asynch, null, state);

            return asynch;
        }