summaryrefslogtreecommitdiffstats
path: root/debian/missing-sources/plupload
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 07:56:53 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 07:56:53 +0000
commita9c818418b81b93680170e1a84d4e221e578ad2f (patch)
tree5b883aa428f1edb12f5d40f9768438ee16a7ed6b /debian/missing-sources/plupload
parentAdding upstream version 6.4.3+dfsg1. (diff)
downloadwordpress-a9c818418b81b93680170e1a84d4e221e578ad2f.tar.xz
wordpress-a9c818418b81b93680170e1a84d4e221e578ad2f.zip
Adding debian version 6.4.3+dfsg1-1.debian/6.4.3+dfsg1-1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/missing-sources/plupload')
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/App.xaml8
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/App.xaml.cs45
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/DCT.cs222
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/DecodedJpeg.cs121
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/HuffmanTable.cs487
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegComponent.cs702
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegDecoder.cs614
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegFrame.cs283
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegHuffmanTable.cs183
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegQuantizationTable.cs116
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegScan.cs37
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Encoder/JpegEncoder.cs327
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/FDCT.cs201
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/Convolution.cs404
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/FilterBase.cs47
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/FilterLowpassResize.cs44
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/FilterNNResize.cs47
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/GrayImage.cs77
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/IJG.txt90
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/IO/BinaryReader.cs46
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/IO/BinaryWriter.cs45
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/IO/JpegBinaryReader.cs117
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Image.cs183
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/JAI.txt40
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/JpegMarker.cs128
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/License.txt24
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/README.txt30
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/Resize/ImageResizer.cs98
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/YCbCr.cs59
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FJCore/ZigZag.cs65
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/FileReference.cs721
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/Page.xaml7
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/Page.xaml.cs230
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/Plupload.csproj222
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/Plupload.sln20
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/PngEncoder/Adler32.cs216
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/PngEncoder/CRC32.cs213
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/PngEncoder/Deflater.cs543
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterConstants.cs184
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterEngine.cs832
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterHuffman.cs881
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterOutputStream.cs469
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterPending.cs55
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/PngEncoder/IChecksum.cs90
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/PngEncoder/PendingBuffer.cs281
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/PngEncoder/PngEncoder.cs467
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/Properties/AppManifest.xml6
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/Properties/AssemblyInfo.cs45
-rw-r--r--debian/missing-sources/plupload/csharp/Plupload/Utils/JsonReader.cs486
-rw-r--r--debian/missing-sources/plupload/flash/plupload/Plupload.as3proj85
-rwxr-xr-xdebian/missing-sources/plupload/flash/plupload/build.sh21
-rw-r--r--debian/missing-sources/plupload/flash/plupload/build.vbs83
-rw-r--r--debian/missing-sources/plupload/flash/plupload/exec.bat13
-rw-r--r--debian/missing-sources/plupload/flash/plupload/src/com/formatlos/BitmapDataUnlimited.as254
-rw-r--r--debian/missing-sources/plupload/flash/plupload/src/com/formatlos/Gif.as197
-rw-r--r--debian/missing-sources/plupload/flash/plupload/src/com/formatlos/events/BitmapDataUnlimitedEvent.as1
-rw-r--r--debian/missing-sources/plupload/flash/plupload/src/com/mxi/BinaryReader.as92
-rw-r--r--debian/missing-sources/plupload/flash/plupload/src/com/mxi/CleanEventDispatcher.as42
-rw-r--r--debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/ExifParser.as417
-rw-r--r--debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/Image.as216
-rw-r--r--debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/JPEG.as186
-rw-r--r--debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/PNG.as77
-rw-r--r--debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/events/ExifParserEvent.as29
-rw-r--r--debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/events/ImageEvent.as36
-rw-r--r--debian/missing-sources/plupload/flash/plupload/src/com/plupload/File.as499
-rw-r--r--debian/missing-sources/plupload/flash/plupload/src/com/plupload/Plupload.as413
-rw-r--r--debian/missing-sources/plupload/flash/plupload/src/com/plupload/UploadChunkEvent.as56
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/cs.js14
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/da.js12
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/de.js24
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/el.js14
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/es.js25
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/et.js33
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/fa.js37
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/fi.js33
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/fr-ca.js35
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/fr.js25
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/hr.js25
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/hu.js33
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/it.js24
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/ja.js37
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/ko.js36
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/lv.js33
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/nl.js21
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/pl.js24
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/pt-br.js35
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/ro.js24
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/ru.js21
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/sk.js25
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/sr.js14
-rw-r--r--debian/missing-sources/plupload/javascript/i18n/sv.js12
-rw-r--r--debian/missing-sources/plupload/javascript/jquery.plupload.queue/css/jquery.plupload.queue.css177
-rw-r--r--debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/backgrounds.gifbin0 -> 2977 bytes
-rw-r--r--debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/buttons-disabled.pngbin0 -> 1292 bytes
-rw-r--r--debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/buttons.pngbin0 -> 1439 bytes
-rw-r--r--debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/delete.gifbin0 -> 180 bytes
-rw-r--r--debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/done.gifbin0 -> 1024 bytes
-rw-r--r--debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/error.gifbin0 -> 994 bytes
-rw-r--r--debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/throbber.gifbin0 -> 1922 bytes
-rw-r--r--debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/transp50.pngbin0 -> 399 bytes
-rw-r--r--debian/missing-sources/plupload/javascript/jquery.plupload.queue/jquery.plupload.queue.js336
-rw-r--r--debian/missing-sources/plupload/javascript/jquery.ui.plupload/css/jquery.ui.plupload.css147
-rw-r--r--debian/missing-sources/plupload/javascript/jquery.ui.plupload/img/plupload-bw.pngbin0 -> 2105 bytes
-rw-r--r--debian/missing-sources/plupload/javascript/jquery.ui.plupload/img/plupload.pngbin0 -> 3641 bytes
-rw-r--r--debian/missing-sources/plupload/javascript/jquery.ui.plupload/jquery.ui.plupload.js754
-rw-r--r--debian/missing-sources/plupload/javascript/plupload.browserplus.js361
-rw-r--r--debian/missing-sources/plupload/javascript/plupload.flash.js431
-rw-r--r--debian/missing-sources/plupload/javascript/plupload.gears.js446
-rw-r--r--debian/missing-sources/plupload/javascript/plupload.html4.js430
-rw-r--r--debian/missing-sources/plupload/javascript/plupload.html5.js1525
-rw-r--r--debian/missing-sources/plupload/javascript/plupload.js1774
-rw-r--r--debian/missing-sources/plupload/javascript/plupload.silverlight.js447
112 files changed, 21019 insertions, 0 deletions
diff --git a/debian/missing-sources/plupload/csharp/Plupload/App.xaml b/debian/missing-sources/plupload/csharp/Plupload/App.xaml
new file mode 100644
index 0000000..32f7a7e
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/App.xaml
@@ -0,0 +1,8 @@
+<Application
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ x:Class="Moxiecode.Plupload.App">
+ <Application.Resources>
+ <!-- Resources scoped at the Application level should be defined here. -->
+ </Application.Resources>
+</Application>
diff --git a/debian/missing-sources/plupload/csharp/Plupload/App.xaml.cs b/debian/missing-sources/plupload/csharp/Plupload/App.xaml.cs
new file mode 100644
index 0000000..9683c6d
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/App.xaml.cs
@@ -0,0 +1,45 @@
+/**
+ * App.xaml.cs
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+using System.Windows;
+using System;
+using System.Windows.Browser;
+
+namespace Moxiecode.Plupload {
+ /// <summary>
+ /// Partial class for the Silverlight application.
+ /// </summary>
+ public partial class App : Application {
+ public App() {
+ this.Startup += this.OnStartup;
+ this.UnhandledException += this.Application_UnhandledException;
+
+ InitializeComponent();
+ }
+
+ private void OnStartup(object sender, StartupEventArgs e) {
+ this.RootVisual = new Page(e.InitParams);
+ }
+
+ private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) {
+ if (!System.Diagnostics.Debugger.IsAttached) {
+ e.Handled = true;
+
+ try {
+ string errorMsg = e.ExceptionObject.Message + @"\n" + e.ExceptionObject.StackTrace;
+ errorMsg = errorMsg.Replace("\"", "\\\"").Replace("\r\n", @"\n");
+
+ System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight 2 Application: " + errorMsg + "\");");
+ } catch (Exception) {
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/DCT.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/DCT.cs
new file mode 100644
index 0000000..e621799
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/DCT.cs
@@ -0,0 +1,222 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt..
+
+// NOTE: Compile with DYNAMIC_IDCT for a decode performance boost.
+// May not yield a perceptible boost for small images,
+// since there is some overhead in emitting CIL dynamically.
+
+using System;
+using System.Reflection.Emit;
+using System.Reflection;
+
+namespace FluxJpeg.Core
+{
+ /// <summary>
+ /// Implements the Discrete Cosine Transform with dynamic CIL
+ /// </summary>
+ public partial class DCT
+ {
+ private float[] _temp = new float[64];
+
+ // Cosine matrix and transposed cosine matrix
+ private static readonly float[,] c = buildC();
+ private static readonly float[,] cT = buildCT();
+
+ internal DCT()
+ {
+ #if DYNAMIC_IDCT
+ dynamicIDCT = dynamicIDCT ?? EmitIDCT();
+ #endif
+ }
+
+ /// <summary>
+ /// Precomputes cosine terms in A.3.3 of
+ /// http://www.w3.org/Graphics/JPEG/itu-t81.pdf
+ ///
+ /// Closely follows the term precomputation in the
+ /// Java Advanced Imaging library.
+ /// </summary>
+ private static float[,] buildC()
+ {
+ float[,] c = new float[8, 8];
+
+ for (int i = 0; i < 8; i++) // i == u or v
+ {
+ for (int j = 0; j < 8; j++) // j == x or y
+ {
+ c[i, j] = i == 0 ?
+ 0.353553391f : /* 1 / SQRT(8) */
+ (float)(0.5 * Math.Cos(((2.0 * j + 1) * i * Math.PI) / 16.0));
+ }
+ }
+
+ return c;
+ }
+ private static float[,] buildCT()
+ {
+ // Transpose i,k <-- j,i
+ float[,] cT = new float[8, 8];
+ for (int i = 0; i < 8; i++)
+ for (int j = 0; j < 8; j++)
+ cT[j, i] = c[i, j];
+ return cT;
+ }
+
+ public static void SetValueClipped(byte[,] arr, int i, int j, float val)
+ {
+ // Clip into the 0...255 range & round
+ arr[i, j] = val < 0 ? (byte)0
+ : val > 255 ? (byte)255
+ : (byte)(val + 0.5);
+ }
+
+ /// See figure A.3.3 IDCT (informative) on A-5.
+ /// http://www.w3.org/Graphics/JPEG/itu-t81.pdf
+ internal byte[,] FastIDCT(float[] input)
+ {
+ byte[,] output = new byte[8, 8];
+
+ #if DYNAMIC_IDCT
+
+ // Fastest, dynamic MSIL stream
+ dynamicIDCT(input, _temp, output);
+
+ #else
+
+ #region Slower, easy-to-read, pure C# IDCT
+
+ float temp, val = 0;
+ int idx = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ for (int j = 0; j < 8; j++)
+ {
+ val = 0;
+
+ for(int k = 0; k < 8; k++)
+ {
+ val += input[i * 8 + k] * c[k, j];
+ }
+
+ _temp[idx++] = val;
+ }
+ }
+ for (int i = 0; i < 8; i++)
+ {
+ for (int j = 0; j < 8; j++)
+ {
+ temp = 128f;
+
+ for (int k = 0; k < 8; k++)
+ {
+ temp += cT[i, k] * _temp[k * 8 + j];
+ }
+
+ if (temp < 0) output[i, j] = 0;
+ else if (temp > 255) output[i, j] = 255;
+ else output[i, j] = (byte)(temp + 0.5); // Implements rounding
+ }
+ }
+
+
+ #endregion
+
+ #endif
+
+ return output;
+ }
+
+
+
+ #if DYNAMIC_IDCT
+
+ /// <summary>
+ /// Generates a pure-IL nonbranching stream of instructions
+ /// that perform the inverse DCT. Relies on helper function
+ /// SetValueClipped.
+ /// </summary>
+ /// <returns>A delegate to the DynamicMethod</returns>
+ private static IDCTFunc EmitIDCT()
+ {
+ Type[] args = { typeof(float[]), typeof(float[]), typeof(byte[,]) };
+
+ DynamicMethod idctMethod = new DynamicMethod("dynamicIDCT",
+ null, // no return type
+ args); // input arrays
+
+ ILGenerator il = idctMethod.GetILGenerator();
+
+ int idx = 0;
+
+ for (int i = 0; i < 8; i++)
+ {
+ for (int j = 0; j < 8; j++)
+ {
+ il.Emit(OpCodes.Ldarg_1); // 1 {temp}
+ il.Emit(OpCodes.Ldc_I4_S, (short)idx++); // 3 {temp, idx}
+
+ for (int k = 0; k < 8; k++)
+ {
+ il.Emit(OpCodes.Ldarg_0); // {in}
+ il.Emit(OpCodes.Ldc_I4_S, (short)(i * 8 + k)); // {in,idx}
+ il.Emit(OpCodes.Ldelem_R4); // {in[idx]}
+ il.Emit(OpCodes.Ldc_R4, c[k, j]); // {in[idx],c[k,j]}
+ il.Emit(OpCodes.Mul); // {in[idx]*c[k,j]}
+ if (k != 0) il.Emit(OpCodes.Add);
+ }
+
+ il.Emit(OpCodes.Stelem_R4); // {}
+ }
+ }
+
+ var meth = typeof(DCT).GetMethod("SetValueClipped",
+ BindingFlags.Static | BindingFlags.Public, null,
+ CallingConventions.Standard,
+ new Type[] {
+ typeof(byte[,]), // arr
+ typeof(int), // i
+ typeof(int), // j
+ typeof(float) } // val
+ , null);
+
+ for (int i = 0; i < 8; i++)
+ {
+ for (int j = 0; j < 8; j++)
+ {
+ il.Emit(OpCodes.Ldarg_2); // {output}
+ il.Emit(OpCodes.Ldc_I4_S, (short)i); // {output,i}
+ il.Emit(OpCodes.Ldc_I4_S, (short)j); // X={output,i,j}
+
+ il.Emit(OpCodes.Ldc_R4, 128.0f); // {X,128.0f}
+
+ for (int k = 0; k < 8; k++)
+ {
+ il.Emit(OpCodes.Ldarg_1); // {X,temp}
+ il.Emit(OpCodes.Ldc_I4_S,
+ (short)(k * 8 + j)); // {X,temp,idx}
+ il.Emit(OpCodes.Ldelem_R4); // {X,temp[idx]}
+ il.Emit(OpCodes.Ldc_R4, cT[i, k]); // {X,temp[idx],cT[i,k]}
+ il.Emit(OpCodes.Mul); // {X,in[idx]*c[k,j]}
+ il.Emit(OpCodes.Add);
+ }
+
+ il.EmitCall(OpCodes.Call, meth, null);
+ }
+ }
+
+ il.Emit(OpCodes.Ret);
+
+ return (IDCTFunc)idctMethod.CreateDelegate(typeof(IDCTFunc));
+ }
+
+ private delegate void IDCTFunc(float[] input, float[] temp, byte[,] output);
+ private static IDCTFunc dynamicIDCT = null;
+#endif
+
+
+ }
+
+
+
+
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/DecodedJpeg.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/DecodedJpeg.cs
new file mode 100644
index 0000000..96ca213
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/DecodedJpeg.cs
@@ -0,0 +1,121 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FluxJpeg.Core
+{
+ public class JpegHeader
+ {
+ public byte Marker;
+ public byte[] Data;
+ internal bool IsJFIF = false;
+ public new string ToString { get { return Encoding.UTF8.GetString(Data, 0, Data.Length); } }
+ }
+
+ public class DecodedJpeg
+ {
+ private Image _image; public Image Image { get { return _image; } }
+
+ internal int[] BlockWidth;
+ internal int[] BlockHeight;
+
+ internal int Precision = 8;
+ internal int[] HsampFactor = { 1, 1, 1 };
+ internal int[] VsampFactor = { 1, 1, 1 };
+ internal bool[] lastColumnIsDummy = new bool[] { false, false, false };
+ internal bool[] lastRowIsDummy = new bool[] { false, false, false };
+
+ internal int[] compWidth, compHeight;
+ internal int MaxHsampFactor;
+ internal int MaxVsampFactor;
+
+ public bool HasJFIF { get; private set; }
+
+ private List<JpegHeader> _metaHeaders;
+
+ public IList<JpegHeader> MetaHeaders { get { return _metaHeaders.AsReadOnly(); } }
+
+ public DecodedJpeg(Image image, IEnumerable<JpegHeader> metaHeaders)
+ {
+ _image = image;
+
+ // Handles null as an empty list
+ _metaHeaders = (metaHeaders == null) ?
+ new List<JpegHeader>(0) : new List<JpegHeader>(metaHeaders);
+
+ // Check if the JFIF header was present
+ foreach (JpegHeader h in _metaHeaders)
+ if (h.IsJFIF) { HasJFIF = true; break; }
+
+ int components = _image.ComponentCount;
+
+ compWidth = new int[components];
+ compHeight = new int[components];
+ BlockWidth = new int[components];
+ BlockHeight = new int[components];
+
+ Initialize();
+ }
+
+ public DecodedJpeg(Image image)
+ : this(image, null)
+ {
+ _metaHeaders = new List<JpegHeader>();
+
+ string comment = "Jpeg Codec | fluxcapacity.net ";
+
+ _metaHeaders.Add(
+ new JpegHeader() {
+ Marker = JPEGMarker.COM,
+ Data = System.Text.Encoding.UTF8.GetBytes(comment)
+ }
+ );
+ }
+
+ /// <summary>
+ /// This method creates and fills three arrays, Y, Cb, and Cr using the input image.
+ /// </summary>
+ private void Initialize()
+ {
+ int w = _image.Width, h = _image.Height;
+
+ int y;
+
+ MaxHsampFactor = 1;
+ MaxVsampFactor = 1;
+
+ for (y = 0; y < _image.ComponentCount; y++)
+ {
+ MaxHsampFactor = Math.Max(MaxHsampFactor, HsampFactor[y]);
+ MaxVsampFactor = Math.Max(MaxVsampFactor, VsampFactor[y]);
+ }
+ for (y = 0; y < _image.ComponentCount; y++)
+ {
+ compWidth[y] = (((w % 8 != 0) ? ((int)Math.Ceiling((double)w / 8.0)) * 8 : w) / MaxHsampFactor) * HsampFactor[y];
+ if (compWidth[y] != ((w / MaxHsampFactor) * HsampFactor[y]))
+ {
+ lastColumnIsDummy[y] = true;
+ }
+
+ // results in a multiple of 8 for compWidthz
+ // this will make the rest of the program fail for the unlikely
+ // event that someone tries to compress an 16 x 16 pixel image
+ // which would of course be worse than pointless
+
+ BlockWidth[y] = (int)Math.Ceiling((double)compWidth[y] / 8.0);
+ compHeight[y] = (((h % 8 != 0) ? ((int)Math.Ceiling((double)h / 8.0)) * 8 : h) / MaxVsampFactor) * VsampFactor[y];
+ if (compHeight[y] != ((h / MaxVsampFactor) * VsampFactor[y]))
+ {
+ lastRowIsDummy[y] = true;
+ }
+
+ BlockHeight[y] = (int)Math.Ceiling((double)compHeight[y] / 8.0);
+ }
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/HuffmanTable.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/HuffmanTable.cs
new file mode 100644
index 0000000..3da2818
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/HuffmanTable.cs
@@ -0,0 +1,487 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+// Partially derives from a Java encoder, JpegEncoder.java by James R Weeks.
+// Implements Baseline JPEG Encoding http://www.opennet.ru/docs/formats/jpeg.txt
+
+using System;
+
+using FluxJpeg.Core.IO;
+using System.IO;
+using System.Collections.Generic;
+
+namespace FluxJpeg.Core
+{
+ internal class HuffmanTable
+ {
+ public static int HUFFMAN_MAX_TABLES = 4;
+
+ private short[] huffcode = new short[256];
+ private short[] huffsize = new short[256];
+ private short[] valptr = new short[16];
+ private short[] mincode = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1,-1};
+ private short[] maxcode = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
+
+ private short[] huffval;
+ private short[] bits;
+
+ int bufferPutBits, bufferPutBuffer;
+ internal int ImageHeight;
+ internal int ImageWidth;
+ internal int[,] DC_matrix0;
+ internal int[,] AC_matrix0;
+ internal int[,] DC_matrix1;
+ internal int[,] AC_matrix1;
+ internal int[][,] DC_matrix;
+ internal int[][,] AC_matrix;
+ internal int NumOfDCTables;
+ internal int NumOfACTables;
+
+ public List<short[]> bitsList;
+ public List<short[]> val;
+
+
+ public static byte JPEG_DC_TABLE = 0;
+ public static byte JPEG_AC_TABLE = 1;
+
+ private short lastk = 0;
+
+ internal HuffmanTable(JpegHuffmanTable table)
+ {
+ if (table != null)
+ {
+ huffval = table.Values;
+ bits = table.Lengths;
+
+ GenerateSizeTable();
+ GenerateCodeTable();
+ GenerateDecoderTables();
+ }
+ else
+ {
+ // Encode initialization
+
+ bitsList = new List<short[]>();
+ bitsList.Add(JpegHuffmanTable.StdDCLuminance.Lengths);
+ bitsList.Add(JpegHuffmanTable.StdACLuminance.Lengths);
+ bitsList.Add(JpegHuffmanTable.StdDCChrominance.Lengths);
+ bitsList.Add(JpegHuffmanTable.StdACChrominance.Lengths);
+
+ val = new List<short[]>();
+ val.Add(JpegHuffmanTable.StdDCLuminance.Values);
+ val.Add(JpegHuffmanTable.StdACLuminance.Values);
+ val.Add(JpegHuffmanTable.StdDCChrominance.Values);
+ val.Add(JpegHuffmanTable.StdACChrominance.Values);
+
+ initHuf();
+ }
+ }
+
+ /// <summary>See Figure C.1</summary>
+ private void GenerateSizeTable()
+ {
+ short index = 0;
+ for (short i = 0; i < bits.Length; i++)
+ {
+ for (short j = 0; j < bits[i]; j++)
+ {
+ huffsize[index] = (short)(i + 1);
+ index++;
+ }
+ }
+ lastk = index;
+ }
+
+ /// <summary>See Figure C.2</summary>
+ private void GenerateCodeTable()
+ {
+ short k = 0;
+ short si = huffsize[0];
+ short code = 0;
+ for (short i = 0; i < huffsize.Length; i++)
+ {
+ while (huffsize[k] == si)
+ {
+ huffcode[k] = code;
+ code++;
+ k++;
+ }
+ code <<= 1;
+ si++;
+ }
+ }
+
+ /// <summary>See figure F.15</summary>
+ private void GenerateDecoderTables()
+ {
+ short bitcount = 0;
+ for (int i = 0; i < 16; i++)
+ {
+ if (bits[i] != 0)
+ valptr[i] = bitcount;
+ for (int j = 0; j < bits[i]; j++)
+ {
+ if (huffcode[j + bitcount] < mincode[i] || mincode[i] == -1)
+ mincode[i] = huffcode[j + bitcount];
+
+ if (huffcode[j + bitcount] > maxcode[i])
+ maxcode[i] = huffcode[j + bitcount];
+ }
+ if (mincode[i] != -1)
+ valptr[i] = (short)(valptr[i] - mincode[i]);
+ bitcount += bits[i];
+ }
+ }
+
+ /// <summary>Figure F.12</summary>
+ public static int Extend(int diff, int t)
+ {
+ // here we use bitshift to implement 2^ ...
+ // NOTE: Math.Pow returns 0 for negative powers, which occassionally happen here!
+
+ int Vt = 1 << t - 1;
+ // WAS: int Vt = (int)Math.Pow(2, (t - 1));
+
+ if (diff < Vt)
+ {
+ Vt = (-1 << t) + 1;
+ diff = diff + Vt;
+ }
+ return diff;
+ }
+
+ /// <summary>Figure F.16 - Reads the huffman code bit-by-bit.</summary>
+ /*public int Decode(JPEGBinaryReader JPEGStream)
+ {
+ int i = 0;
+ short code = (short)JPEGStream.ReadBits(1);
+ while (code > maxcode[i])
+ {
+ i++;
+ code <<= 1;
+ code |= (short)JPEGStream.ReadBits(1);
+ }
+ int val = huffval[code + (valptr[i])];
+ if (val < 0)
+ val = 256 + val;
+ return val;
+ }*/
+
+ /// <summary>
+ /// HuffmanBlockEncoder run length encodes and Huffman encodes the quantized data.
+ /// </summary>
+ internal void HuffmanBlockEncoder(Stream outStream, int[] zigzag, int prec, int DCcode, int ACcode)
+ {
+ int temp, temp2, nbits, k, r, i;
+
+ NumOfDCTables = 2;
+ NumOfACTables = 2;
+
+ // The DC portion
+
+ temp = temp2 = zigzag[0] - prec;
+ if (temp < 0)
+ {
+ temp = -temp;
+ temp2--;
+ }
+ nbits = 0;
+ while (temp != 0)
+ {
+ nbits++;
+ temp >>= 1;
+ }
+ // if (nbits > 11) nbits = 11;
+ bufferIt(outStream,
+ DC_matrix[DCcode][nbits, 0],
+ DC_matrix[DCcode][nbits, 1]);
+
+ // The arguments in bufferIt are code and size.
+ if (nbits != 0)
+ {
+ bufferIt(outStream, temp2, nbits);
+ }
+
+ // The AC portion
+
+ r = 0;
+
+ for (k = 1; k < 64; k++)
+ {
+ if ((temp = zigzag[ ZigZag.ZigZagMap[k] ]) == 0)
+ {
+ r++;
+ }
+ else
+ {
+ while (r > 15)
+ {
+ bufferIt(outStream,
+ AC_matrix[ACcode][0xF0, 0],
+ AC_matrix[ACcode][0xF0, 1]);
+
+ r -= 16;
+ }
+ temp2 = temp;
+ if (temp < 0)
+ {
+ temp = -temp;
+ temp2--;
+ }
+ nbits = 1;
+ while ((temp >>= 1) != 0)
+ {
+ nbits++;
+ }
+ i = (r << 4) + nbits;
+ bufferIt(outStream,
+ AC_matrix[ACcode][i, 0],
+ AC_matrix[ACcode][i, 1]);
+ bufferIt(outStream, temp2, nbits);
+
+ r = 0;
+ }
+ }
+
+ if (r > 0)
+ {
+ bufferIt(outStream,
+ AC_matrix[ACcode][0, 0],
+ AC_matrix[ACcode][0, 1]);
+ }
+ }
+
+ /// <summary>
+ /// Uses an integer long (32 bits) buffer to store the Huffman encoded bits
+ /// and sends them to outStream by the byte.
+ /// </summary>
+ void bufferIt(Stream outStream, int code, int size)
+ {
+ int PutBuffer = code;
+ int PutBits = bufferPutBits;
+
+ PutBuffer &= (1 << size) - 1;
+ PutBits += size;
+ PutBuffer <<= 24 - PutBits;
+ PutBuffer |= bufferPutBuffer;
+
+ while (PutBits >= 8)
+ {
+ int c = ((PutBuffer >> 16) & 0xFF);
+ outStream.WriteByte((byte)c);
+
+ // FF must be escaped
+ if (c == 0xFF) outStream.WriteByte(0);
+
+ PutBuffer <<= 8;
+ PutBits -= 8;
+ }
+ bufferPutBuffer = PutBuffer;
+ bufferPutBits = PutBits;
+
+ }
+
+ public void FlushBuffer(Stream outStream)
+ {
+ int PutBuffer = bufferPutBuffer;
+ int PutBits = bufferPutBits;
+ while (PutBits >= 8)
+ {
+ int c = ((PutBuffer >> 16) & 0xFF);
+ outStream.WriteByte((byte)c);
+
+ // FF must be escaped
+ if (c == 0xFF) outStream.WriteByte(0);
+
+ PutBuffer <<= 8;
+ PutBits -= 8;
+ }
+ if (PutBits > 0)
+ {
+ int c = ((PutBuffer >> 16) & 0xFF);
+ outStream.WriteByte((byte)c);
+ }
+ }
+
+
+ /// <summary>
+ /// Initialisation of the Huffman codes for Luminance and Chrominance.
+ /// This code results in the same tables created in the IJG Jpeg-6a
+ /// library.
+ /// </summary>
+ public void initHuf()
+ {
+ DC_matrix0 = new int[12, 2];
+ DC_matrix1 = new int[12, 2];
+ AC_matrix0 = new int[255, 2];
+ AC_matrix1 = new int[255, 2];
+ DC_matrix = new int[2][,];
+ AC_matrix = new int[2][,];
+ int p, l, i, lastp, si, code;
+ int[] huffsize = new int[257];
+ int[] huffcode = new int[257];
+
+ short[] bitsDCchrominance = JpegHuffmanTable.StdDCChrominance.Lengths;
+ short[] bitsACchrominance = JpegHuffmanTable.StdACChrominance.Lengths;
+ short[] bitsDCluminance = JpegHuffmanTable.StdDCLuminance.Lengths;
+ short[] bitsACluminance = JpegHuffmanTable.StdACLuminance.Lengths;
+
+
+ short[] valDCchrominance = JpegHuffmanTable.StdDCChrominance.Values;
+ short[] valACchrominance = JpegHuffmanTable.StdACChrominance.Values;
+ short[] valDCluminance = JpegHuffmanTable.StdDCLuminance.Values;
+ short[] valACluminance = JpegHuffmanTable.StdACLuminance.Values;
+
+
+ /*
+ * init of the DC values for the chrominance
+ * [,0] is the code [,1] is the number of bit
+ */
+
+ p = 0;
+ for (l = 0; l < 16; l++)
+ {
+ for (i = 1; i <= bitsDCchrominance[l]; i++)
+ {
+ huffsize[p++] = l+1;
+ }
+ }
+
+ huffsize[p] = 0;
+ lastp = p;
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p] != 0)
+ {
+ while (huffsize[p] == si)
+ {
+ huffcode[p++] = code;
+ code++;
+ }
+ code <<= 1;
+ si++;
+ }
+
+ for (p = 0; p < lastp; p++)
+ {
+ DC_matrix1[valDCchrominance[p], 0] = huffcode[p];
+ DC_matrix1[valDCchrominance[p], 1] = huffsize[p];
+ }
+
+ /*
+ * Init of the AC hufmann code for the chrominance
+ * matrix [,,0] is the code & matrix[,,1] is the number of bit needed
+ */
+
+ p = 0;
+ for (l = 0; l < 16; l++)
+ {
+ for (i = 1; i <= bitsACchrominance[l]; i++)
+ {
+ huffsize[p++] = l+1;
+ }
+ }
+ huffsize[p] = 0;
+ lastp = p;
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p] != 0)
+ {
+ while (huffsize[p] == si)
+ {
+ huffcode[p++] = code;
+ code++;
+ }
+ code <<= 1;
+ si++;
+ }
+
+ for (p = 0; p < lastp; p++)
+ {
+ AC_matrix1[valACchrominance[p], 0] = huffcode[p];
+ AC_matrix1[valACchrominance[p], 1] = huffsize[p];
+ }
+
+ /*
+ * init of the DC values for the luminance
+ * [,0] is the code [,1] is the number of bit
+ */
+ p = 0;
+ for (l = 0; l < 16; l++)
+ {
+ for (i = 1; i <= bitsDCluminance[l]; i++)
+ {
+ huffsize[p++] = l+1;
+ }
+ }
+ huffsize[p] = 0;
+ lastp = p;
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p] != 0)
+ {
+ while (huffsize[p] == si)
+ {
+ huffcode[p++] = code;
+ code++;
+ }
+ code <<= 1;
+ si++;
+ }
+
+ for (p = 0; p < lastp; p++)
+ {
+ DC_matrix0[valDCluminance[p], 0] = huffcode[p];
+ DC_matrix0[valDCluminance[p], 1] = huffsize[p];
+ }
+
+ /*
+ * Init of the AC hufmann code for luminance
+ * matrix [,,0] is the code & matrix[,,1] is the number of bit
+ */
+
+ p = 0;
+ for (l = 0; l < 16; l++)
+ {
+ for (i = 1; i <= bitsACluminance[l]; i++)
+ {
+ huffsize[p++] = l+1;
+ }
+ }
+ huffsize[p] = 0;
+ lastp = p;
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p] != 0)
+ {
+ while (huffsize[p] == si)
+ {
+ huffcode[p++] = code;
+ code++;
+ }
+ code <<= 1;
+ si++;
+ }
+ for (int q = 0; q < lastp; q++)
+ {
+ AC_matrix0[valACluminance[q], 0] = huffcode[q];
+ AC_matrix0[valACluminance[q], 1] = huffsize[q];
+ }
+
+ DC_matrix[0] = DC_matrix0;
+ DC_matrix[1] = DC_matrix1;
+ AC_matrix[0] = AC_matrix0;
+ AC_matrix[1] = AC_matrix1;
+ }
+
+
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegComponent.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegComponent.cs
new file mode 100644
index 0000000..4d8c8e0
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegComponent.cs
@@ -0,0 +1,702 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using FluxJpeg.Core.IO;
+using System.Reflection.Emit;
+using System.Diagnostics;
+
+namespace FluxJpeg.Core.Decoder
+{
+
+ internal class JpegComponent
+ {
+ public byte factorH, factorV, component_id, quant_id;
+ public int width = 0, height = 0;
+ public HuffmanTable ACTable;
+ public HuffmanTable DCTable;
+
+ public int[] QuantizationTable {
+ set
+ {
+ quantizationTable = value;
+ _quant = EmitQuantize();
+ }
+ }
+ private int[] quantizationTable;
+
+ public float previousDC = 0;
+ private JpegScan parent;
+
+ // Current MCU block
+ float[,][] scanMCUs = null;
+
+ private List<float[,][]> scanData = new List<float[,][]>();
+
+ public int BlockCount { get { return scanData.Count; } }
+
+ private List<byte[,]> scanDecoded = new List<byte[,]>();
+
+ public int spectralStart, spectralEnd;
+ public int successiveLow;
+
+ public JpegComponent(JpegScan parentScan, byte id, byte factorHorizontal, byte factorVertical,
+ byte quantizationID, byte colorMode)
+ {
+ parent = parentScan;
+
+ /* Set default tables in case they're not provided. J. Powers */
+ // TODO: only gen if needed
+
+ if (colorMode == JPEGFrame.JPEG_COLOR_YCbCr)
+ {
+ if (id == 1) // Luminance
+ {
+ ACTable = new HuffmanTable(JpegHuffmanTable.StdACLuminance);
+ DCTable = new HuffmanTable(JpegHuffmanTable.StdDCLuminance);
+ }
+ else
+ {
+ ACTable = new HuffmanTable( JpegHuffmanTable.StdACChrominance);
+ DCTable = new HuffmanTable( JpegHuffmanTable.StdACLuminance);
+ }
+ }
+
+ component_id = id;
+
+ factorH = factorHorizontal;
+ factorV = factorVertical;
+
+ quant_id = quantizationID;
+ }
+
+ /// <summary>
+ /// If a restart marker is found with too little of an MCU count (i.e. our
+ /// Restart Interval is 63 and we have 61 we copy the last MCU until it's full)
+ /// </summary>
+ public void padMCU(int index, int length)
+ {
+ scanMCUs = new float[factorH, factorV][];
+
+ for(int n = 0; n < length; n++)
+ {
+ if (scanData.Count >= (index + length)) continue;
+
+ for (int i = 0; i < factorH; i++)
+ for (int j = 0; j < factorV; j++)
+ scanMCUs[i, j] = (float[])scanData[index - 1][i,j].Clone();
+
+ scanData.Add(scanMCUs);
+ }
+
+ }
+
+ /// <summary>
+ /// Reset the interval by setting the previous DC value
+ /// </summary>
+ public void resetInterval()
+ {
+ previousDC = 0;
+ }
+
+ private delegate void QuantizeDel(float[] arr);
+ private QuantizeDel _quant = null;
+
+ private QuantizeDel EmitQuantize()
+ {
+ Type[] args = { typeof(float[]) };
+
+ DynamicMethod quantizeMethod = new DynamicMethod("Quantize",
+ null, // no return type
+ args); // input array
+
+ ILGenerator il = quantizeMethod.GetILGenerator();
+
+ for (int i = 0; i < quantizationTable.Length; i++)
+ {
+ float mult = (float)quantizationTable[i];
+
+ // Sz Stack:
+ il.Emit(OpCodes.Ldarg_0); // 1 {arr}
+ il.Emit(OpCodes.Ldc_I4_S, (short)i); // 3 {arr,i}
+ il.Emit(OpCodes.Ldarg_0); // 1 {arr,i,arr}
+ il.Emit(OpCodes.Ldc_I4_S, (short)i); // 3 {arr,i,arr,i}
+ il.Emit(OpCodes.Ldelem_R4); // 1 {arr,i,arr[i]}
+ il.Emit(OpCodes.Ldc_R4, mult); // 5 {arr,i,arr[i],mult}
+ il.Emit(OpCodes.Mul); // 1 {arr,i,arr[i]*mult}
+ il.Emit(OpCodes.Stelem_R4); // 1 {}
+
+ }
+
+ il.Emit(OpCodes.Ret);
+
+ return (QuantizeDel)quantizeMethod.CreateDelegate(typeof(QuantizeDel));
+ }
+
+ /// <summary>
+ /// Run the Quantization backward method on all of the block data.
+ /// </summary>
+ public void quantizeData()
+ {
+ for (int i = 0; i < scanData.Count; i++)
+ {
+ for(int v = 0; v < factorV; v++)
+ for (int h = 0; h < factorH; h++)
+ {
+ // Dynamic IL method
+ _quant(scanData[i][h, v]);
+
+ // Old technique
+ //float[] toQuantize = scanData[i][h, v];
+ //for (int j = 0; j < 64; j++) toQuantize[j] *= quantizationTable[j];
+ }
+ }
+
+ }
+
+ public void setDCTable(JpegHuffmanTable table)
+ {
+ DCTable = new HuffmanTable(table);
+ }
+
+ public void setACTable(JpegHuffmanTable table)
+ {
+ ACTable = new HuffmanTable(table);
+ }
+
+ DCT _dct = new DCT();
+
+ /// <summary>
+ /// Run the Inverse DCT method on all of the block data
+ /// </summary>
+ public void idctData()
+ {
+ float[] unZZ = new float[64];
+ float[] toDecode = null;
+
+ for (int i = 0; i < scanData.Count; i++)
+ {
+ for (int v = 0; v < factorV; v++)
+ for (int h = 0; h < factorH; h++)
+ {
+ toDecode = scanData[i][h, v];
+ ZigZag.UnZigZag(toDecode, unZZ);
+ //FJCore.Profiling.IDCTWatch.Start();
+ scanDecoded.Add(_dct.FastIDCT(unZZ));
+ //FJCore.Profiling.IDCTWatch.Stop();
+ }
+ }
+ }
+
+ private int factorUpV { get { return parent.MaxV / factorV; } }
+ private int factorUpH { get { return parent.MaxH / factorH; } }
+
+
+ /// <summary>
+ /// Stretches components as needed to normalize the size of all components.
+ /// For example, in a 2x1 (4:2:2) sequence, the Cr and Cb channels will be
+ /// scaled vertically by a factor of 2.
+ /// </summary>
+ public void scaleByFactors( BlockUpsamplingMode mode )
+ {
+ int factorUpVertical = factorUpV,
+ factorUpHorizontal = factorUpH;
+
+ if (factorUpVertical == 1 && factorUpHorizontal == 1) return;
+
+ for (int i = 0; i < scanDecoded.Count; i++)
+ {
+ byte[,] src = scanDecoded[i];
+
+ int oldV = src.GetLength(0),
+ oldH = src.GetLength(1),
+ newV = oldV * factorUpVertical,
+ newH = oldH * factorUpHorizontal;
+
+ byte[,] dest = new byte[newV, newH];
+
+ switch (mode)
+ {
+ case BlockUpsamplingMode.BoxFilter:
+ #region Upsampling by repeating values
+ /* Perform scaling (Box filter) */
+ for (int u = 0; u < newH; u++)
+ {
+ int src_u = u / factorUpHorizontal;
+ for (int v = 0; v < newV; v++)
+ {
+ int src_v = v / factorUpVertical;
+ dest[v, u] = src[src_v, src_u];
+ }
+ }
+ #endregion
+ break;
+
+ case BlockUpsamplingMode.Interpolate:
+ #region Upsampling by interpolation
+
+ for (int u = 0; u < newH; u++)
+ {
+ for (int v = 0; v < newV; v++)
+ {
+ int val = 0;
+
+ for (int x = 0; x < factorUpHorizontal; x++)
+ {
+ int src_u = (u + x) / factorUpHorizontal;
+ if (src_u >= oldH) src_u = oldH - 1;
+
+ for (int y = 0; y < factorUpVertical; y++)
+ {
+ int src_v = (v + y) / factorUpVertical;
+
+ if (src_v >= oldV) src_v = oldV - 1;
+
+ val += src[src_v, src_u];
+ }
+ }
+
+ dest[v, u] = (byte)(val / (factorUpHorizontal * factorUpVertical));
+ }
+ }
+
+ #endregion
+ break;
+
+ default:
+ throw new ArgumentException("Upsampling mode not supported.");
+ }
+
+ scanDecoded[i] = dest;
+ }
+
+ }
+
+
+ public void writeBlock(byte[][,] raster, byte[,] data,
+ int compIndex, int x, int y)
+ {
+ int w = raster[0].GetLength(0),
+ h = raster[0].GetLength(1);
+
+ byte[,] comp = raster[compIndex];
+
+ // Blocks may spill over the frame so we bound by the frame size
+ int yMax = data.GetLength(0); if ((y + yMax) > h) yMax = h - y;
+ int xMax = data.GetLength(1); if ((x + xMax) > w) xMax = w - x;
+
+ for (int yIndex = 0; yIndex < yMax; yIndex++)
+ {
+ for (int xIndex = 0; xIndex < xMax; xIndex++)
+ {
+ comp[x + xIndex, y + yIndex] = data[yIndex, xIndex];
+ }
+ }
+ }
+
+ public void writeDataScaled(byte[][,] raster, int componentIndex, BlockUpsamplingMode mode)
+ {
+ int x = 0, y = 0, lastblockheight = 0, incrementblock = 0;
+
+ int blockIdx = 0;
+
+ int w = raster[0].GetLength(0),
+ h = raster[0].GetLength(1);
+
+ // Keep looping through all of the blocks until there are no more.
+ while (blockIdx < scanDecoded.Count)
+ {
+ int blockwidth = 0;
+ int blockheight = 0;
+
+ if (x >= w) { x = 0; y += incrementblock; }
+
+ // Loop through the horizontal component blocks of the MCU first
+ // then for each horizontal line write out all of the vertical
+ // components
+ for (int factorVIndex = 0; factorVIndex < factorV; factorVIndex++)
+ {
+ blockwidth = 0;
+
+ for (int factorHIndex = 0; factorHIndex < factorH; factorHIndex++)
+ {
+ // Captures the width of this block so we can increment the X coordinate
+ byte[,] blockdata = scanDecoded[blockIdx++];
+
+ // Writes the data at the specific X and Y coordinate of this component
+ writeBlockScaled(raster, blockdata, componentIndex, x, y, mode);
+
+ blockwidth += blockdata.GetLength(1) * factorUpH;
+ x += blockdata.GetLength(1) * factorUpH;
+ blockheight = blockdata.GetLength(0) * factorUpV;
+ }
+
+ y += blockheight;
+ x -= blockwidth;
+ lastblockheight += blockheight;
+ }
+ y -= lastblockheight;
+ incrementblock = lastblockheight;
+ lastblockheight = 0;
+ x += blockwidth;
+ }
+ }
+
+ private void writeBlockScaled(byte[][,] raster, byte[,] blockdata, int compIndex, int x, int y, BlockUpsamplingMode mode)
+ {
+ int w = raster[0].GetLength(0),
+ h = raster[0].GetLength(1);
+
+ int factorUpVertical = factorUpV,
+ factorUpHorizontal = factorUpH;
+
+ int oldV = blockdata.GetLength(0),
+ oldH = blockdata.GetLength(1),
+ newV = oldV * factorUpVertical,
+ newH = oldH * factorUpHorizontal;
+
+ byte[,] comp = raster[compIndex];
+
+ // Blocks may spill over the frame so we bound by the frame size
+ int yMax = newV; if ((y + yMax) > h) yMax = h - y;
+ int xMax = newH; if ((x + xMax) > w) xMax = w - x;
+
+ switch (mode)
+ {
+ case BlockUpsamplingMode.BoxFilter:
+
+ #region Upsampling by repeating values
+
+ // Special case 1: No scale-up
+ if (factorUpVertical == 1 && factorUpHorizontal == 1)
+ {
+ for (int u = 0; u < xMax; u++)
+ for (int v = 0; v < yMax; v++)
+ comp[u + x, y + v] = blockdata[v, u];
+ }
+ // Special case 2: Perform scale-up 4 pixels at a time
+ else if (factorUpHorizontal == 2 &&
+ factorUpVertical == 2 &&
+ xMax == newH && yMax == newV)
+ {
+ for (int src_u = 0; src_u < oldH; src_u++)
+ {
+ int bx = src_u * 2 + x;
+
+ for ( int src_v = 0; src_v < oldV; src_v++)
+ {
+ byte val = blockdata[src_v, src_u];
+ int by = src_v * 2 + y;
+
+ comp[bx, by] = val;
+ comp[bx, by + 1] = val;
+ comp[bx + 1, by] = val;
+ comp[bx + 1, by + 1] = val;
+ }
+ }
+ }
+ else
+ {
+ /* Perform scaling (Box filter) */
+ for (int u = 0; u < xMax; u++)
+ {
+ int src_u = u / factorUpHorizontal;
+ for (int v = 0; v < yMax; v++)
+ {
+ int src_v = v / factorUpVertical;
+ comp[u + x, y + v] = blockdata[src_v, src_u];
+ }
+ }
+ }
+
+
+ #endregion
+ break;
+
+ // JRP 4/7/08 -- This mode is disabled temporarily as it needs to be fixed after
+ // recent performance tweaks.
+ // It can produce slightly better (less blocky) decodings.
+
+ //case BlockUpsamplingMode.Interpolate:
+ // #region Upsampling by interpolation
+ // for (int u = 0; u < newH; u++)
+ // {
+ // for (int v = 0; v < newV; v++)
+ // {
+ // int val = 0;
+ // for (int x = 0; x < factorUpHorizontal; x++)
+ // {
+ // int src_u = (u + x) / factorUpHorizontal;
+ // if (src_u >= oldH) src_u = oldH - 1;
+ // for (int y = 0; y < factorUpVertical; y++)
+ // {
+ // int src_v = (v + y) / factorUpVertical;
+ // if (src_v >= oldV) src_v = oldV - 1;
+ // val += src[src_v, src_u];
+ // }
+ // }
+ // dest[v, u] = (byte)(val / (factorUpHorizontal * factorUpVertical));
+ // }
+ // }
+ // #endregion
+ // break;
+
+ default:
+ throw new ArgumentException("Upsampling mode not supported.");
+ }
+
+ }
+
+
+
+
+ internal delegate void DecodeFunction(JPEGBinaryReader jpegReader, float[] zigzagMCU);
+ public DecodeFunction Decode;
+
+ public void DecodeBaseline(JPEGBinaryReader stream, float[] dest)
+ {
+ float dc = decode_dc_coefficient(stream);
+ decode_ac_coefficients(stream, dest);
+ dest[0] = dc;
+ }
+
+ public void DecodeDCFirst(JPEGBinaryReader stream, float[] dest)
+ {
+ float[] datablock = new float[64];
+ int s = DCTable.Decode(stream);
+ int r = stream.ReadBits(s);
+ s = HuffmanTable.Extend(r, s);
+ s = (int)previousDC + s;
+ previousDC = s;
+
+ dest[0] = s << successiveLow;
+ }
+
+ public void DecodeACFirst(JPEGBinaryReader stream, float[] zz)
+ {
+ if (stream.eob_run > 0)
+ {
+ stream.eob_run--;
+ return;
+ }
+
+ for (int k = spectralStart; k <= spectralEnd; k++)
+ {
+ int s = ACTable.Decode(stream);
+ int r = s >> 4;
+ s &= 15;
+
+
+ if (s != 0)
+ {
+ k += r;
+
+ r = (int)stream.ReadBits(s);
+ s = (int)HuffmanTable.Extend(r, s);
+ zz[k] = s << successiveLow;
+ }
+ else
+ {
+ if (r != 15)
+ {
+ stream.eob_run = 1 << r;
+
+ if (r != 0)
+ stream.eob_run += stream.ReadBits(r);
+
+ stream.eob_run--;
+
+ break;
+ }
+
+ k += 15;
+ }
+ }
+ }
+
+ public void DecodeDCRefine(JPEGBinaryReader stream, float[] dest)
+ {
+ if (stream.ReadBits(1) == 1)
+ {
+ dest[0] = (int)dest[0] | (1 << successiveLow);
+ }
+ }
+
+ public void DecodeACRefine(JPEGBinaryReader stream, float[] dest)
+ {
+ int p1 = 1 << successiveLow;
+ int m1 = (-1) << successiveLow;
+
+ int k = spectralStart;
+
+ if (stream.eob_run == 0)
+ for (; k <= spectralEnd; k++)
+ {
+ #region Decode and check S
+
+ int s = ACTable.Decode(stream);
+ int r = s >> 4;
+ s &= 15;
+
+ if (s != 0)
+ {
+ if (s != 1)
+ throw new Exception("Decode Error");
+
+ if (stream.ReadBits(1) == 1)
+ s = p1;
+ else
+ s = m1;
+ }
+ else
+ {
+ if (r != 15)
+ {
+ stream.eob_run = 1 << r;
+
+ if (r > 0)
+ stream.eob_run += stream.ReadBits(r);
+ break;
+ }
+
+ } // if (s != 0)
+
+ #endregion
+
+ // Apply the update
+ do
+ {
+ if (dest[k] != 0)
+ {
+ if (stream.ReadBits(1) == 1)
+ {
+ if (((int)dest[k] & p1) == 0)
+ {
+ if (dest[k] >= 0)
+ dest[k] += p1;
+ else
+ dest[k] += m1;
+ }
+ }
+ }
+ else
+ {
+ if (--r < 0)
+ break;
+ }
+
+ k++;
+
+ } while (k <= spectralEnd);
+
+ if( (s != 0) && k < 64)
+ {
+ dest[k] = s;
+ }
+ } // for k = start ... end
+
+
+ if (stream.eob_run > 0)
+ {
+ for (; k <= spectralEnd; k++)
+ {
+ if (dest[k] != 0)
+ {
+ if (stream.ReadBits(1) == 1)
+ {
+ if (((int)dest[k] & p1) == 0)
+ {
+ if (dest[k] >= 0)
+ dest[k] += p1;
+ else
+ dest[k] += m1;
+ }
+ }
+ }
+ }
+
+ stream.eob_run--;
+ }
+ }
+
+
+ public void SetBlock(int idx)
+ {
+ if (scanData.Count < idx)
+ throw new Exception("Invalid block ID.");
+
+ // expand the data list
+ if (scanData.Count == idx)
+ {
+ scanMCUs = new float[factorH, factorV][];
+ for (int i = 0; i < factorH; i++)
+ for (int j = 0; j < factorV; j++)
+ scanMCUs[i, j] = new float[64];
+
+ scanData.Add(scanMCUs);
+ }
+ else // reference an existing block
+ {
+ scanMCUs = scanData[idx];
+ }
+ }
+
+ public void DecodeMCU(JPEGBinaryReader jpegReader, int i, int j)
+ {
+ Decode(jpegReader, scanMCUs[i,j]);
+ }
+
+ /// <summary>
+ /// Generated from text on F-22, F.2.2.1 - Huffman decoding of DC
+ /// coefficients on ISO DIS 10918-1. Requirements and Guidelines.
+ /// </summary>
+ /// <param name="JPEGStream">Stream that contains huffman bits</param>
+ /// <returns>DC coefficient</returns>
+ public float decode_dc_coefficient(JPEGBinaryReader JPEGStream)
+ {
+ int t = DCTable.Decode(JPEGStream);
+ float diff = JPEGStream.ReadBits(t);
+ diff = HuffmanTable.Extend((int)diff, t);
+ diff = (previousDC + diff);
+ previousDC = diff;
+ return diff;
+ }
+
+
+ /// <summary>
+ /// Generated from text on F-23, F.13 - Huffman decoded of AC coefficients
+ /// on ISO DIS 10918-1. Requirements and Guidelines.
+ /// </summary>
+ internal void decode_ac_coefficients(JPEGBinaryReader JPEGStream, float[] zz)
+ {
+ for (int k = 1; k < 64; k++)
+ {
+ int s = ACTable.Decode(JPEGStream);
+ int r = s >> 4;
+ s &= 15;
+
+
+ if (s != 0)
+ {
+ k += r;
+
+ r = (int)JPEGStream.ReadBits(s);
+ s = (int)HuffmanTable.Extend(r, s);
+ zz[k] = s;
+ }
+ else
+ {
+ if (r != 15)
+ {
+ //throw new JPEGMarkerFoundException();
+ return;
+ }
+ k += 15;
+ }
+ }
+ }
+ }
+
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegDecoder.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegDecoder.cs
new file mode 100644
index 0000000..6e654db
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegDecoder.cs
@@ -0,0 +1,614 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using FluxJpeg.Core.IO;
+using System.Diagnostics;
+
+namespace FluxJpeg.Core.Decoder
+{
+ public enum BlockUpsamplingMode {
+ /// <summary> The simplest upsampling mode. Produces sharper edges. </summary>
+ BoxFilter,
+ /// <summary> Smoother upsampling. May improve color spread for some images. </summary>
+ Interpolate
+ }
+
+ public class JpegDecodeProgressChangedArgs : EventArgs
+ {
+ public bool SizeReady;
+ public int Width;
+ public int Height;
+
+ public bool Abort;
+ public long ReadPosition; // 0 to input stream length
+ public double DecodeProgress; // 0 to 1.0
+ }
+
+ public class JpegDecoder
+ {
+ public static long ProgressUpdateByteInterval = 100;
+
+ public event EventHandler<JpegDecodeProgressChangedArgs> DecodeProgressChanged;
+ private JpegDecodeProgressChangedArgs DecodeProgress = new JpegDecodeProgressChangedArgs();
+
+ public BlockUpsamplingMode BlockUpsamplingMode { get; set; }
+
+ byte majorVersion, minorVersion;
+ private enum UnitType { None = 0, Inches = 1, Centimeters = 2 };
+ UnitType Units;
+ ushort XDensity, YDensity;
+ byte Xthumbnail, Ythumbnail;
+ byte[] thumbnail;
+ Image image;
+ int width;
+ int height;
+
+ bool progressive = false;
+
+ byte marker;
+
+ /// <summary>
+ /// This decoder expects JFIF 1.02 encoding.
+ /// </summary>
+ internal const byte MAJOR_VERSION = (byte)1;
+ internal const byte MINOR_VERSION = (byte)2;
+
+ /// <summary>
+ /// The length of the JFIF field not including thumbnail data.
+ /// </summary>
+ internal static short JFIF_FIXED_LENGTH = 16;
+
+ /// <summary>
+ /// The length of the JFIF extension field not including extension data.
+ /// </summary>
+ internal static short JFXX_FIXED_LENGTH = 8;
+
+ private JPEGBinaryReader jpegReader;
+
+ List<JPEGFrame> jpegFrames = new List<JPEGFrame>();
+
+ JpegHuffmanTable[] dcTables = new JpegHuffmanTable[4];
+ JpegHuffmanTable[] acTables = new JpegHuffmanTable[4];
+ JpegQuantizationTable[] qTables = new JpegQuantizationTable[4];
+
+ public JpegDecoder(Stream input)
+ {
+ jpegReader = new JPEGBinaryReader(input);
+
+ if (jpegReader.GetNextMarker() != JPEGMarker.SOI)
+ throw new Exception("Failed to find SOI marker.");
+ }
+
+ /// <summary>
+ /// Tries to parse the JFIF APP0 header
+ /// See http://en.wikipedia.org/wiki/JFIF
+ /// </summary>
+ private bool TryParseJFIF(byte[] data)
+ {
+ IO.BinaryReader reader = new IO.BinaryReader(new MemoryStream(data));
+
+ int length = data.Length + 2; // Data & length
+
+ if (!(length >= JFIF_FIXED_LENGTH))
+ return false; // Header's too small.
+
+ byte[] identifier = new byte[5];
+ reader.Read(identifier, 0, identifier.Length);
+ if (identifier[0] != JPEGMarker.JFIF_J
+ || identifier[1] != JPEGMarker.JFIF_F
+ || identifier[2] != JPEGMarker.JFIF_I
+ || identifier[3] != JPEGMarker.JFIF_F
+ || identifier[4] != JPEGMarker.X00)
+ return false; // Incorrect bytes
+
+ majorVersion = reader.ReadByte();
+ minorVersion = reader.ReadByte();
+ if (majorVersion != MAJOR_VERSION
+ || (majorVersion == MAJOR_VERSION
+ && minorVersion > MINOR_VERSION)) // changed from <
+ return false; // Unsupported version
+
+ Units = (UnitType)reader.ReadByte();
+ if (Units != UnitType.None &&
+ Units != UnitType.Inches &&
+ Units != UnitType.Centimeters)
+ return false; // Invalid units
+
+ XDensity = reader.ReadShort();
+ YDensity = reader.ReadShort();
+ Xthumbnail = reader.ReadByte();
+ Ythumbnail = reader.ReadByte();
+
+ // 3 * for RGB data
+ int thumbnailLength = 3 * Xthumbnail * Ythumbnail;
+ if (length > JFIF_FIXED_LENGTH
+ && thumbnailLength != length - JFIF_FIXED_LENGTH)
+ return false; // Thumbnail fields invalid
+
+ if (thumbnailLength > 0)
+ {
+ thumbnail = new byte[thumbnailLength];
+ if (reader.Read(thumbnail, 0, thumbnailLength) != thumbnailLength)
+ return false; // Thumbnail data was missing!
+
+ }
+
+ return true;
+ }
+
+ public DecodedJpeg Decode()
+ {
+ // The frames in this jpeg are loaded into a list. There is
+ // usually just one frame except in heirarchial progression where
+ // there are multiple frames.
+ JPEGFrame frame = null;
+
+ // The restart interval defines how many MCU's we should have
+ // between the 8-modulo restart marker. The restart markers allow
+ // us to tell whether or not our decoding process is working
+ // correctly, also if there is corruption in the image we can
+ // recover with these restart intervals. (See RSTm DRI).
+ int resetInterval = 0;
+
+ bool haveMarker = false;
+ bool foundJFIF = false;
+
+ List<JpegHeader> headers = new List<JpegHeader>();
+
+ // Loop through until there are no more markers to read in, at
+ // that point everything is loaded into the jpegFrames array and
+ // can be processed.
+ while (true)
+ {
+ if (DecodeProgress.Abort) return null;
+
+ #region Switch over marker types
+ switch (marker)
+ {
+ case JPEGMarker.APP0:
+ // APP1 is used for EXIF data
+ case JPEGMarker.APP1:
+ // Seldomly, APP2 gets used for extended EXIF, too
+ case JPEGMarker.APP2:
+ case JPEGMarker.APP3:
+ case JPEGMarker.APP4:
+ case JPEGMarker.APP5:
+ case JPEGMarker.APP6:
+ case JPEGMarker.APP7:
+ case JPEGMarker.APP8:
+ case JPEGMarker.APP9:
+ case JPEGMarker.APP10:
+ case JPEGMarker.APP11:
+ case JPEGMarker.APP12:
+ case JPEGMarker.APP13:
+ case JPEGMarker.APP14:
+ case JPEGMarker.APP15:
+ // COM: Comment
+ case JPEGMarker.COM:
+
+ // Debug.WriteLine(string.Format("Extracting Header, Type={0:X}", marker));
+
+ JpegHeader header = ExtractHeader();
+
+ #region Check explicitly for Exif Data
+
+ if (header.Marker == JPEGMarker.APP1 && header.Data.Length >= 6)
+ {
+ byte[] d = header.Data;
+
+ if( d[0] == 'E' &&
+ d[1] == 'x' &&
+ d[2] == 'i' &&
+ d[3] == 'f' &&
+ d[4] == 0 &&
+ d[5] == 0)
+ {
+ // Exif. Do something?
+ }
+ }
+
+ #endregion
+
+ #region Check for Adobe header
+
+ if (header.Data.Length >= 5 && header.Marker == JPEGMarker.APP14)
+ {
+ string asText = UTF8Encoding.UTF8.GetString(header.Data, 0, 5);
+ if (asText == "Adobe") {
+ // ADOBE HEADER. Do anything?
+ }
+ }
+
+ #endregion
+
+ headers.Add(header);
+
+ if (!foundJFIF && marker == JPEGMarker.APP0)
+ {
+ foundJFIF = TryParseJFIF(header.Data);
+
+ if (foundJFIF) // Found JFIF... do JFIF extension follow?
+ {
+ header.IsJFIF = true;
+ marker = jpegReader.GetNextMarker();
+
+ // Yes, they do.
+ if (marker == JPEGMarker.APP0)
+ {
+ header = ExtractHeader();
+ headers.Add(header);
+ }
+ else // No. Delay processing this one.
+ haveMarker = true;
+ }
+ }
+
+ break;
+
+ case JPEGMarker.SOF0:
+ case JPEGMarker.SOF2:
+
+ // SOFn Start of Frame Marker, Baseline DCT - This is the start
+ // of the frame header that defines certain variables that will
+ // be carried out through the rest of the encoding. Multiple
+ // frames are used in a hierarchical system, however most JPEG's
+ // only contain a single frame.
+
+ // Progressive or baseline?
+ progressive = marker == JPEGMarker.SOF2;
+
+ jpegFrames.Add(new JPEGFrame());
+ frame = (JPEGFrame)jpegFrames[jpegFrames.Count - 1];
+ frame.ProgressUpdateMethod = new Action<long>(UpdateStreamProgress);
+
+ // Skip the frame length.
+ jpegReader.ReadShort();
+ // Bits percision, either 8 or 12.
+ frame.setPrecision(jpegReader.ReadByte());
+ // Scan lines (height)
+ frame.ScanLines = jpegReader.ReadShort();
+ // Scan samples per line (width)
+ frame.SamplesPerLine = jpegReader.ReadShort();
+ // Number of Color Components (channels).
+ frame.ComponentCount = jpegReader.ReadByte();
+
+ DecodeProgress.Height = frame.Height;
+ DecodeProgress.Width = frame.Width;
+ DecodeProgress.SizeReady = true;
+
+ if(DecodeProgressChanged != null)
+ {
+ DecodeProgressChanged(this, DecodeProgress);
+ if (DecodeProgress.Abort) return null;
+ }
+
+ // Add all of the necessary components to the frame.
+ for (int i = 0; i < frame.ComponentCount; i++)
+ {
+ byte compId = jpegReader.ReadByte();
+ byte sampleFactors = jpegReader.ReadByte();
+ byte qTableId = jpegReader.ReadByte();
+
+ byte sampleHFactor = (byte)(sampleFactors >> 4);
+ byte sampleVFactor = (byte)(sampleFactors & 0x0f);
+
+ frame.AddComponent(compId, sampleHFactor, sampleVFactor, qTableId);
+ }
+ break;
+
+ case JPEGMarker.DHT:
+
+ // DHT non-SOF Marker - Huffman Table is required for decoding
+ // the JPEG stream, when we receive a marker we load in first
+ // the table length (16 bits), the table class (4 bits), table
+ // identifier (4 bits), then we load in 16 bytes and each byte
+ // represents the count of bytes to load in for each of the 16
+ // bytes. We load this into an array to use later and move on 4
+ // huffman tables can only be used in an image.
+ int huffmanLength = (jpegReader.ReadShort() - 2);
+
+ // Keep looping until we are out of length.
+ int index = huffmanLength;
+
+ // Multiple tables may be defined within a DHT marker. This
+ // will keep reading until there are no tables left, most
+ // of the time there are just one tables.
+ while (index > 0)
+ {
+ // Read the identifier information and class
+ // information about the Huffman table, then read the
+ // 16 byte codelength in and read in the Huffman values
+ // and put it into table info.
+ byte huffmanInfo = jpegReader.ReadByte();
+ byte tableClass = (byte)(huffmanInfo >> 4);
+ byte huffmanIndex = (byte)(huffmanInfo & 0x0f);
+ short[] codeLength = new short[16];
+
+ for (int i = 0; i < codeLength.Length; i++)
+ codeLength[i] = jpegReader.ReadByte();
+
+ int huffmanValueLen = 0;
+ for (int i = 0; i < 16; i++)
+ huffmanValueLen += codeLength[i];
+ index -= (huffmanValueLen + 17);
+
+ short[] huffmanVal = new short[huffmanValueLen];
+ for (int i = 0; i < huffmanVal.Length; i++)
+ {
+ huffmanVal[i] = jpegReader.ReadByte();
+ }
+ // Assign DC Huffman Table.
+ if (tableClass == HuffmanTable.JPEG_DC_TABLE)
+ dcTables[(int)huffmanIndex] = new JpegHuffmanTable(codeLength, huffmanVal);
+
+ // Assign AC Huffman Table.
+ else if (tableClass == HuffmanTable.JPEG_AC_TABLE)
+ acTables[(int)huffmanIndex] = new JpegHuffmanTable(codeLength, huffmanVal);
+ }
+ break;
+
+ case JPEGMarker.DQT:
+
+ // DQT non-SOF Marker - This defines the quantization
+ // coeffecients, this allows us to figure out the quality of
+ // compression and unencode the data. The data is loaded and
+ // then stored in to an array.
+ short quantizationLength = (short)(jpegReader.ReadShort() - 2);
+ for (int j = 0; j < quantizationLength / 65; j++)
+ {
+ byte quantSpecs = jpegReader.ReadByte();
+ int[] quantData = new int[64];
+ if ((byte)(quantSpecs >> 4) == 0)
+ // Precision 8 bit.
+ {
+ for (int i = 0; i < 64; i++)
+ quantData[i] = jpegReader.ReadByte();
+
+ }
+ else if ((byte)(quantSpecs >> 4) == 1)
+ // Precision 16 bit.
+ {
+ for (int i = 0; i < 64; i++)
+ quantData[i] = jpegReader.ReadShort();
+ }
+ qTables[(int)(quantSpecs & 0x0f)] = new JpegQuantizationTable(quantData);
+ }
+ break;
+
+ case JPEGMarker.SOS:
+
+ Debug.WriteLine("Start of Scan (SOS)");
+
+
+ // SOS non-SOF Marker - Start Of Scan Marker, this is where the
+ // actual data is stored in a interlaced or non-interlaced with
+ // from 1-4 components of color data, if three components most
+ // likely a YCrCb model, this is a fairly complex process.
+
+ // Read in the scan length.
+ ushort scanLen = jpegReader.ReadShort();
+ // Number of components in the scan.
+ byte numberOfComponents = jpegReader.ReadByte();
+ byte[] componentSelector = new byte[numberOfComponents];
+
+ for (int i = 0; i < numberOfComponents; i++)
+ {
+ // Component ID, packed byte containing the Id for the
+ // AC table and DC table.
+ byte componentID = jpegReader.ReadByte();
+ byte tableInfo = jpegReader.ReadByte();
+
+ int DC = (tableInfo >> 4) & 0x0f;
+ int AC = (tableInfo) & 0x0f;
+
+ frame.setHuffmanTables(componentID,
+ acTables[(byte)AC],
+ dcTables[(byte)DC]);
+
+
+ componentSelector[i] = componentID;
+ }
+
+ byte startSpectralSelection = jpegReader.ReadByte();
+ byte endSpectralSelection = jpegReader.ReadByte();
+ byte successiveApproximation = jpegReader.ReadByte();
+
+ #region Baseline JPEG Scan Decoding
+
+ if (!progressive)
+ {
+ frame.DecodeScanBaseline(numberOfComponents, componentSelector, resetInterval, jpegReader, ref marker);
+ haveMarker = true; // use resultant marker for the next switch(..)
+ }
+
+ #endregion
+
+ #region Progressive JPEG Scan Decoding
+
+ if (progressive)
+ {
+ frame.DecodeScanProgressive(
+ successiveApproximation, startSpectralSelection, endSpectralSelection,
+ numberOfComponents, componentSelector, resetInterval, jpegReader, ref marker);
+
+ haveMarker = true; // use resultant marker for the next switch(..)
+ }
+
+ #endregion
+
+ break;
+
+
+ case JPEGMarker.DRI:
+ jpegReader.BaseStream.Seek(2, System.IO.SeekOrigin.Current);
+ resetInterval = jpegReader.ReadShort();
+ break;
+
+ /// Defines the number of lines. (Not usually present)
+ case JPEGMarker.DNL:
+
+ frame.ScanLines = jpegReader.ReadShort();
+ break;
+
+ /// End of Image. Finish the decode.
+ case JPEGMarker.EOI:
+
+ if (jpegFrames.Count == 0)
+ {
+ throw new NotSupportedException("No JPEG frames could be located.");
+ }
+ else if (jpegFrames.Count == 1)
+ {
+ // Only one frame, JPEG Non-Heirarchial Frame.
+ byte[][,] raster = Image.CreateRaster(frame.Width, frame.Height, frame.ComponentCount);
+
+ IList<JpegComponent> components = frame.Scan.Components;
+
+ int totalSteps = components.Count * 3; // Three steps per loop
+ int stepsFinished = 0;
+
+ for(int i = 0; i < components.Count; i++)
+ {
+ JpegComponent comp = components[i];
+
+ comp.QuantizationTable = qTables[comp.quant_id].Table;
+
+ // 1. Quantize
+ comp.quantizeData();
+ UpdateProgress(++stepsFinished, totalSteps);
+
+ // 2. Run iDCT (expensive)
+ comp.idctData();
+ UpdateProgress(++stepsFinished, totalSteps);
+
+ // 3. Scale the image and write the data to the raster.
+ comp.writeDataScaled(raster, i, BlockUpsamplingMode);
+
+ UpdateProgress(++stepsFinished, totalSteps);
+
+ // Ensure garbage collection.
+ comp = null; GC.Collect();
+ }
+
+ // Grayscale Color Image (1 Component).
+ if (frame.ComponentCount == 1)
+ {
+ ColorModel cm = new ColorModel() { colorspace = ColorSpace.Gray, Opaque = true };
+ image = new Image(cm, raster);
+ }
+ // YCbCr Color Image (3 Components).
+ else if (frame.ComponentCount == 3)
+ {
+ ColorModel cm = new ColorModel() { colorspace = ColorSpace.YCbCr, Opaque = true };
+ image = new Image(cm, raster);
+ }
+ // Possibly CMYK or RGBA ?
+ else
+ {
+ throw new NotSupportedException("Unsupported Color Mode: 4 Component Color Mode found.");
+ }
+
+ // If needed, convert centimeters to inches.
+ Func<double, double> conv = x =>
+ Units == UnitType.Inches ? x : x / 2.54;
+
+ image.DensityX = conv(XDensity);
+ image.DensityY = conv(YDensity);
+
+ height = frame.Height;
+ width = frame.Width;
+ }
+ else
+ {
+ // JPEG Heirarchial Frame
+ throw new NotSupportedException("Unsupported Codec Type: Hierarchial JPEG");
+ }
+ break;
+
+ // Only SOF0 (baseline) and SOF2 (progressive) are supported by FJCore
+ case JPEGMarker.SOF1:
+ case JPEGMarker.SOF3:
+ case JPEGMarker.SOF5:
+ case JPEGMarker.SOF6:
+ case JPEGMarker.SOF7:
+ case JPEGMarker.SOF9:
+ case JPEGMarker.SOF10:
+ case JPEGMarker.SOF11:
+ case JPEGMarker.SOF13:
+ case JPEGMarker.SOF14:
+ case JPEGMarker.SOF15:
+ throw new NotSupportedException("Unsupported codec type.");
+
+ default: break; // ignore
+
+ }
+
+ #endregion switch over markers
+
+ if (haveMarker) haveMarker = false;
+ else
+ {
+ try
+ {
+ marker = jpegReader.GetNextMarker();
+ }
+ catch (System.IO.EndOfStreamException)
+ {
+ break; /* done reading the file */
+ }
+ }
+ }
+
+ DecodedJpeg result = new DecodedJpeg(image, headers);
+
+ return result;
+ }
+
+ private JpegHeader ExtractHeader()
+ {
+ #region Extract the header
+
+ int length = jpegReader.ReadShort() - 2;
+ byte[] data = new byte[length];
+ jpegReader.Read(data, 0, length);
+
+ #endregion
+
+ JpegHeader header = new JpegHeader()
+ {
+ Marker = marker,
+ Data = data
+ };
+ return header;
+ }
+
+ #region Decode Progress Monitoring
+
+ private void UpdateStreamProgress(long StreamPosition)
+ {
+ if (DecodeProgressChanged != null)
+ {
+ DecodeProgress.ReadPosition = StreamPosition;
+ DecodeProgressChanged(this, DecodeProgress);
+ };
+ }
+
+ private void UpdateProgress(int stepsFinished, int stepsTotal)
+ {
+ if (DecodeProgressChanged != null)
+ {
+ DecodeProgress.DecodeProgress = (double)stepsFinished / stepsTotal;
+ DecodeProgressChanged(this, DecodeProgress);
+ };
+ }
+
+ #endregion
+
+
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegFrame.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegFrame.cs
new file mode 100644
index 0000000..02f8027
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegFrame.cs
@@ -0,0 +1,283 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using FluxJpeg.Core.IO;
+
+namespace FluxJpeg.Core.Decoder
+{
+ internal class JPEGFrame
+ {
+ public static byte JPEG_COLOR_GRAY = 1;
+ public static byte JPEG_COLOR_RGB = 2;
+ public static byte JPEG_COLOR_YCbCr = 3;
+ public static byte JPEG_COLOR_CMYK = 4;
+
+ public byte precision = 8;
+ public byte colorMode = JPEGFrame.JPEG_COLOR_YCbCr;
+
+ public ushort Width { get; private set; }
+ public ushort Height { get; private set; }
+
+ public JpegScan Scan = new JpegScan();
+
+ public Action<long> ProgressUpdateMethod = null;
+
+ public void AddComponent(byte componentID, byte sampleHFactor, byte sampleVFactor,
+ byte quantizationTableID)
+ {
+ Scan.AddComponent(componentID, sampleHFactor, sampleVFactor, quantizationTableID, colorMode);
+ }
+
+ public void setPrecision(byte data) { precision = data; }
+
+ public ushort ScanLines { set { Height = value; } }
+ public ushort SamplesPerLine { set { Width = value; } }
+
+ public byte ColorMode { get {
+ return ComponentCount == 1 ?
+ JPEGFrame.JPEG_COLOR_GRAY :
+ JPEGFrame.JPEG_COLOR_YCbCr;
+
+ }
+ }
+
+ public byte ComponentCount { get ; set; }
+
+ public void setHuffmanTables(byte componentID, JpegHuffmanTable ACTable, JpegHuffmanTable DCTable)
+ {
+ JpegComponent comp = Scan.GetComponentById(componentID);
+
+ if(DCTable != null) comp.setDCTable(DCTable);
+ if(ACTable != null) comp.setACTable(ACTable);
+ }
+
+ public void DecodeScanBaseline(byte numberOfComponents, byte[] componentSelector, int resetInterval, JPEGBinaryReader jpegReader, ref byte marker)
+ {
+ // Set the decode function for all the components
+ for (int compIndex = 0; compIndex < numberOfComponents; compIndex++)
+ {
+ JpegComponent comp = Scan.GetComponentById(componentSelector[compIndex]);
+ comp.Decode = comp.DecodeBaseline;
+ }
+
+ DecodeScan(numberOfComponents, componentSelector, resetInterval, jpegReader, ref marker);
+ }
+
+ private int mcus_per_row(JpegComponent c)
+ {
+ return (((( Width * c.factorH ) + ( Scan.MaxH - 1)) / Scan.MaxH) + 7) / 8;
+ }
+
+ private void DecodeScan(byte numberOfComponents, byte[] componentSelector, int resetInterval, JPEGBinaryReader jpegReader, ref byte marker)
+ {
+ //TODO: not necessary
+ jpegReader.eob_run = 0;
+
+ int mcuIndex = 0;
+ int mcuTotalIndex = 0;
+
+ // This loops through until a MarkerTagFound exception is
+ // found, if the marker tag is a RST (Restart Marker) it
+ // simply skips it and moves on this system does not handle
+ // corrupt data streams very well, it could be improved by
+ // handling misplaced restart markers.
+
+ int h = 0, v = 0;
+ int x = 0;
+
+ long lastPosition = jpegReader.BaseStream.Position;
+
+ //TODO: replace this with a loop which knows how much data to expect
+ while (true)
+ {
+ #region Inform caller of decode progress
+
+ if (ProgressUpdateMethod != null)
+ {
+ if (jpegReader.BaseStream.Position >= lastPosition + JpegDecoder.ProgressUpdateByteInterval)
+ {
+ lastPosition = jpegReader.BaseStream.Position;
+ ProgressUpdateMethod(lastPosition);
+ }
+ }
+
+ #endregion
+
+ try
+ {
+ // Loop though capturing MCU, instruct each
+ // component to read in its necessary count, for
+ // scaling factors the components automatically
+ // read in how much they need
+
+ // Sec A.2.2 from CCITT Rec. T.81 (1992 E)
+ bool interleaved = !(numberOfComponents == 1);
+
+ if (!interleaved)
+ {
+ JpegComponent comp = Scan.GetComponentById(componentSelector[0]);
+
+ comp.SetBlock(mcuIndex);
+
+ comp.DecodeMCU(jpegReader, h, v);
+
+ int mcus_per_line = mcus_per_row(comp);
+ int blocks_per_line = (int) Math.Ceiling((double)this.Width / (8 * comp.factorH));
+
+
+ // TODO: Explain the non-interleaved scan ------
+
+ h++; x++;
+
+ if (h == comp.factorH)
+ {
+ h = 0; mcuIndex++;
+ }
+
+ if( (x % mcus_per_line) == 0)
+ {
+ x = 0;
+ v++;
+
+ if (v == comp.factorV)
+ {
+ if (h != 0) { mcuIndex++; h = 0; }
+ v = 0;
+ }
+ else
+ {
+ mcuIndex -= blocks_per_line;
+
+ // we were mid-block
+ if (h != 0) { mcuIndex++; h = 0; }
+ }
+ }
+
+ // -----------------------------------------------
+
+ }
+ else // Components are interleaved
+ {
+ for (int compIndex = 0; compIndex < numberOfComponents; compIndex++)
+ {
+ JpegComponent comp = Scan.GetComponentById(componentSelector[compIndex]);
+ comp.SetBlock(mcuTotalIndex);
+
+ for (int j = 0; j < comp.factorV; j++)
+ for (int i = 0; i < comp.factorH; i++)
+ {
+ comp.DecodeMCU(jpegReader, i, j);
+ }
+ }
+
+ mcuIndex++;
+ mcuTotalIndex++;
+ }
+ }
+ // We've found a marker, see if the marker is a restart
+ // marker or just the next marker in the stream. If
+ // it's the next marker in the stream break out of the
+ // while loop, if it's just a restart marker skip it
+ catch (JPEGMarkerFoundException ex)
+ {
+ marker = ex.Marker;
+
+ // Handle JPEG Restart Markers, this is where the
+ // count of MCU's per interval is compared with
+ // the count actually obtained, if it's short then
+ // pad on some MCU's ONLY for components that are
+ // greater than one. Also restart the DC prediction
+ // to zero.
+ if (marker == JPEGMarker.RST0
+ || marker == JPEGMarker.RST1
+ || marker == JPEGMarker.RST2
+ || marker == JPEGMarker.RST3
+ || marker == JPEGMarker.RST4
+ || marker == JPEGMarker.RST5
+ || marker == JPEGMarker.RST6
+ || marker == JPEGMarker.RST7)
+ {
+ for (int compIndex = 0; compIndex < numberOfComponents; compIndex++)
+ {
+ JpegComponent comp = Scan.GetComponentById(componentSelector[compIndex]);
+ if (compIndex > 1)
+ comp.padMCU(mcuTotalIndex, resetInterval - mcuIndex);
+ comp.resetInterval();
+ }
+
+ mcuTotalIndex += (resetInterval - mcuIndex);
+ mcuIndex = 0;
+ }
+ else
+ {
+ break; // We're at the end of our scan, exit out.
+ }
+ }
+ }
+
+ }
+
+ public void DecodeScanProgressive(byte successiveApproximation, byte startSpectralSelection, byte endSpectralSelection,
+ byte numberOfComponents, byte[] componentSelector, int resetInterval, JPEGBinaryReader jpegReader, ref byte marker)
+ {
+
+ byte successiveHigh = (byte)(successiveApproximation >> 4);
+ byte successiveLow = (byte)(successiveApproximation & 0x0f);
+
+ if ((startSpectralSelection > endSpectralSelection) || (endSpectralSelection > 63))
+ throw new Exception("Bad spectral selection.");
+
+ bool dcOnly = startSpectralSelection == 0;
+ bool refinementScan = (successiveHigh != 0);
+
+ if (dcOnly) // DC scan
+ {
+ if (endSpectralSelection != 0)
+ throw new Exception("Bad spectral selection for DC only scan.");
+ }
+ else // AC scan
+ {
+ if (numberOfComponents > 1)
+ throw new Exception("Too many components for AC scan!");
+ }
+
+ // Set the decode function for all the components
+ // TODO: set this for the scan and let the component figure it out
+ for (int compIndex = 0; compIndex < numberOfComponents; compIndex++)
+ {
+ JpegComponent comp = Scan.GetComponentById(componentSelector[compIndex]);
+
+ comp.successiveLow = successiveLow;
+
+ if (dcOnly)
+ {
+ if (refinementScan) // DC refine
+ comp.Decode = comp.DecodeDCRefine;
+ else // DC first
+ comp.Decode = comp.DecodeDCFirst;
+ }
+ else
+ {
+ comp.spectralStart = startSpectralSelection;
+ comp.spectralEnd = endSpectralSelection;
+
+ if (refinementScan) // AC refine
+ comp.Decode = comp.DecodeACRefine;
+ else // AC first
+ comp.Decode = comp.DecodeACFirst;
+ }
+ }
+
+ DecodeScan(numberOfComponents, componentSelector, resetInterval, jpegReader, ref marker);
+
+ }
+
+
+
+ }
+
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegHuffmanTable.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegHuffmanTable.cs
new file mode 100644
index 0000000..cb4b8f1
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegHuffmanTable.cs
@@ -0,0 +1,183 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+using System.Linq;
+
+namespace FluxJpeg.Core
+{
+ /// <summary>
+ /// The JPEGHuffmanTable class represents a Huffman table read from a
+ /// JPEG image file. The standard JPEG AC and DC chrominance and
+ /// luminance values are provided as static fields.
+ /// </summary>
+ internal class JpegHuffmanTable
+ {
+ private short[] lengths;
+ private short[] values;
+
+ #region Standard JPEG Huffman Tables
+
+ public static JpegHuffmanTable StdACChrominance =
+ new JpegHuffmanTable(new short[] { 0, 2, 1, 2, 4, 4, 3, 4, 7, 5,
+ 4, 4, 0, 1, 2, 0x77 },
+ new short[] { 0x00, 0x01, 0x02, 0x03, 0x11,
+ 0x04, 0x05, 0x21, 0x31, 0x06,
+ 0x12, 0x41, 0x51, 0x07, 0x61,
+ 0x71, 0x13, 0x22, 0x32, 0x81,
+ 0x08, 0x14, 0x42, 0x91, 0xa1,
+ 0xb1, 0xc1, 0x09, 0x23, 0x33,
+ 0x52, 0xf0, 0x15, 0x62, 0x72,
+ 0xd1, 0x0a, 0x16, 0x24, 0x34,
+ 0xe1, 0x25, 0xf1, 0x17, 0x18,
+ 0x19, 0x1a, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x43, 0x44,
+ 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4a, 0x53, 0x54, 0x55, 0x56,
+ 0x57, 0x58, 0x59, 0x5a, 0x63,
+ 0x64, 0x65, 0x66, 0x67, 0x68,
+ 0x69, 0x6a, 0x73, 0x74, 0x75,
+ 0x76, 0x77, 0x78, 0x79, 0x7a,
+ 0x82, 0x83, 0x84, 0x85, 0x86,
+ 0x87, 0x88, 0x89, 0x8a, 0x92,
+ 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0xa2, 0xa3,
+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
+ 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
+ 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
+ 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+ 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
+ 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
+ 0xd7, 0xd8, 0xd9, 0xda, 0xe2,
+ 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xf2, 0xf3,
+ 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa }, false);
+
+ public static JpegHuffmanTable StdACLuminance =
+ new JpegHuffmanTable(new short[] { 0, 2, 1, 3, 3, 2, 4, 3, 5, 5,
+ 4, 4, 0, 0, 1, 0x7d },
+ new short[] { 0x01, 0x02, 0x03, 0x00, 0x04,
+ 0x11, 0x05, 0x12, 0x21, 0x31,
+ 0x41, 0x06, 0x13, 0x51, 0x61,
+ 0x07, 0x22, 0x71, 0x14, 0x32,
+ 0x81, 0x91, 0xa1, 0x08, 0x23,
+ 0x42, 0xb1, 0xc1, 0x15, 0x52,
+ 0xd1, 0xf0, 0x24, 0x33, 0x62,
+ 0x72, 0x82, 0x09, 0x0a, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x25,
+ 0x26, 0x27, 0x28, 0x29, 0x2a,
+ 0x34, 0x35, 0x36, 0x37, 0x38,
+ 0x39, 0x3a, 0x43, 0x44, 0x45,
+ 0x46, 0x47, 0x48, 0x49, 0x4a,
+ 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x63, 0x64,
+ 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6a, 0x73, 0x74, 0x75, 0x76,
+ 0x77, 0x78, 0x79, 0x7a, 0x83,
+ 0x84, 0x85, 0x86, 0x87, 0x88,
+ 0x89, 0x8a, 0x92, 0x93, 0x94,
+ 0x95, 0x96, 0x97, 0x98, 0x99,
+ 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+ 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
+ 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
+ 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xd2, 0xd3,
+ 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
+ 0xd9, 0xda, 0xe1, 0xe2, 0xe3,
+ 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
+ 0xe9, 0xea, 0xf1, 0xf2, 0xf3,
+ 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa }, false);
+
+ public static JpegHuffmanTable StdDCChrominance =
+ new JpegHuffmanTable(new short[] { 0, 3, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0 },
+ new short[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11 }, false);
+
+ public static JpegHuffmanTable StdDCLuminance =
+ new JpegHuffmanTable(new short[] { 0, 1, 5, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0 },
+ new short[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11 }, false);
+
+ #endregion
+
+
+ /// <summary>
+ /// Construct and initialize a Huffman table. Copies are created of
+ /// the array arguments. lengths[index] stores the number of Huffman
+ /// values with Huffman codes of length index + 1. The values array
+ /// stores the Huffman values in order of increasing code length.
+ ///
+ /// throws ArgumentException if either parameter is null, if
+ /// lengths.Length > 16 or values.Length > 256, if any value in
+ /// length or values is negative, or if the parameters do not
+ /// describe a valid Huffman table
+ /// </summary>
+ /// <param name="lengths"> an array of Huffman code lengths</param>
+ /// <param name="values">a sorted array of Huffman values</param>
+ public JpegHuffmanTable(short[] lengths, short[] values)
+ // Create copies of the lengths and values arguments.
+ : this(checkLengths(lengths), checkValues(values, lengths), true)
+ {
+ }
+
+ /// <summary>
+ /// Private constructor that avoids unnecessary copying and argument checking.
+ /// </summary>
+ /// <param name="lengths">lengths an array of Huffman code lengths</param>
+ /// <param name="values">a sorted array of Huffman values</param>
+ /// <param name="copy">true if copies should be created of the given arrays</param>
+ private JpegHuffmanTable(short[] lengths, short[] values, bool copy)
+ {
+ this.lengths = copy ? (short[])lengths.Clone() : lengths;
+ this.values = copy ? (short[])values.Clone() : values;
+ }
+
+ private static short[] checkLengths(short[] lengths)
+ {
+ if (lengths == null || lengths.Length > 16)
+ throw new ArgumentException("Length array is null or too long.");
+
+ if(lengths.Any(x => x < 0))
+ throw new ArgumentException("Negative values cannot appear in the length array.");
+
+ for (int i = 0; i < lengths.Length; i++)
+ {
+ if (lengths[i] > ((1 << (i + 1)) - 1))
+ throw new ArgumentException(
+ string.Format("Invalid number of codes for code length {0}", (i + 1).ToString() ));
+ }
+
+ return lengths;
+ }
+
+ private static short[] checkValues(short[] values, short[] lengths)
+ {
+ if (values == null || values.Length > 256)
+ throw new ArgumentException("Values array is null or too long.");
+
+ if (values.Any(x => x < 0))
+ throw new ArgumentException("Negative values cannot appear in the values array.");
+
+ if (values.Length != lengths.Sum(x => (int)x))
+ throw new ArgumentException("Number of values does not match code length sum.");
+
+ return values;
+ }
+
+ /// <summary>
+ /// Retrieve the array of Huffman code lengths. If the
+ /// returned array is called lengthcount, there are
+ /// lengthcount[index] codes of length index + 1.
+ /// </summary>
+ public short[] Lengths { get { return lengths; } }
+ public short[] Values { get { return values; } }
+
+ }
+
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegQuantizationTable.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegQuantizationTable.cs
new file mode 100644
index 0000000..d1f073a
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegQuantizationTable.cs
@@ -0,0 +1,116 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+
+namespace FluxJpeg.Core
+{
+ internal class JpegQuantizationTable
+ {
+ // The table entries, stored in natural order.
+ private int[] table; public int[] Table { get { return table; } }
+
+ /// <summary>
+ /// The standard JPEG luminance quantization table. Values are
+ /// stored in natural order.
+ /// </summary>
+ public static JpegQuantizationTable K1Luminance = new JpegQuantizationTable(new int[]
+ {
+ 16, 11, 10, 16, 24, 40, 51, 61,
+ 12, 12, 14, 19, 26, 58, 60, 55,
+ 14, 13, 16, 24, 40, 57, 69, 56,
+ 14, 17, 22, 29, 51, 87, 80, 62,
+ 18, 22, 37, 56, 68, 109, 103, 77,
+ 24, 35, 55, 64, 81, 104, 113, 92,
+ 49, 64, 78, 87, 103, 121, 120, 101,
+ 72, 92, 95, 98, 112, 100, 103, 99
+ }, false);
+
+ /// <summary>
+ /// The standard JPEG luminance quantization table, scaled by
+ /// one-half. Values are stored in natural order.
+ /// </summary>
+ public static JpegQuantizationTable K1Div2Luminance =
+ K1Luminance.getScaledInstance(0.5f, true);
+
+ /// <summary>
+ /// The standard JPEG chrominance quantization table. Values are
+ /// stored in natural order.
+ /// </summary>
+ public static JpegQuantizationTable K2Chrominance = new JpegQuantizationTable(new int[]
+ {
+ 17, 18, 24, 47, 99, 99, 99, 99,
+ 18, 21, 26, 66, 99, 99, 99, 99,
+ 24, 26, 56, 99, 99, 99, 99, 99,
+ 47, 66, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99
+ }, false);
+
+ /// <summary>
+ /// The standard JPEG chrominance quantization table, scaled by
+ /// one-half. Values are stored in natural order.
+ /// </summary>
+ public static JpegQuantizationTable K2Div2Chrominance =
+ K2Chrominance.getScaledInstance(0.5f, true);
+
+ /// <summary>
+ /// Construct a new JPEG quantization table. A copy is created of
+ /// the table argument.
+ /// </summary>
+ /// <param name="table">The 64-element value table, stored in natural order</param>
+ public JpegQuantizationTable(int[] table)
+ : this(checkTable(table), true)
+ {
+ }
+
+ /// <summary>
+ /// Private constructor that avoids unnecessary copying and argument
+ /// checking.
+ /// </summary>
+ /// <param name="table">the 64-element value table, stored in natural order</param>
+ /// <param name="copy">true if a copy should be created of the given table</param>
+ private JpegQuantizationTable(int[] table, bool copy)
+ {
+ this.table = copy ? (int[])table.Clone() : table;
+ }
+
+ private static int[] checkTable(int[] table)
+ {
+ if (table == null || table.Length != 64)
+ throw new ArgumentException("Invalid JPEG quantization table");
+
+ return table;
+ }
+
+ /// <summary>
+ /// Retrieve a copy of this JPEG quantization table with every value
+ /// scaled by the given scale factor, and clamped from 1 to 255
+ /// </summary>
+ /// <param name="scaleFactor">the factor by which to scale this table</param>
+ /// <param name="forceBaseline"> clamp scaled values to a maximum of 255 if baseline or from 1 to 32767 otherwise.</param>
+ /// <returns>new scaled JPEG quantization table</returns>
+ public JpegQuantizationTable getScaledInstance(float scaleFactor,
+ bool forceBaseline)
+ {
+ int[] scaledTable = (int[])table.Clone();
+ int max = forceBaseline ? 255 : 32767;
+
+ for (int i = 0; i < scaledTable.Length; i++)
+ {
+ scaledTable[i] = (int)Math.Round(scaleFactor * (float)scaledTable[i]);
+ if (scaledTable[i] < 1)
+ scaledTable[i] = 1;
+ else if (scaledTable[i] > max)
+ scaledTable[i] = max;
+ }
+
+ return new JpegQuantizationTable(scaledTable, false);
+ }
+
+ }
+
+
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegScan.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegScan.cs
new file mode 100644
index 0000000..38e1911
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Decoder/JpegScan.cs
@@ -0,0 +1,37 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace FluxJpeg.Core.Decoder
+{
+ internal class JpegScan
+ {
+ private List<JpegComponent> components = new List<JpegComponent>();
+ public IList<JpegComponent> Components { get { return components.AsReadOnly(); } }
+
+ private int maxV = 0, maxH = 0;
+ internal int MaxH { get { return maxH; } }
+ internal int MaxV { get { return maxV; } }
+
+ public void AddComponent(byte id, byte factorHorizontal, byte factorVertical,
+ byte quantizationID, byte colorMode)
+ {
+ JpegComponent component = new JpegComponent( this,
+ id, factorHorizontal, factorVertical, quantizationID, colorMode);
+
+ components.Add(component);
+
+ // Defined in Annex A
+ maxH = components.Max(x => x.factorH);
+ maxV = components.Max(x => x.factorV);
+ }
+
+ public JpegComponent GetComponentById(byte Id)
+ {
+ return components.First(x => x.component_id == Id);
+ }
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Encoder/JpegEncoder.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Encoder/JpegEncoder.cs
new file mode 100644
index 0000000..3ff9a93
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Encoder/JpegEncoder.cs
@@ -0,0 +1,327 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+//
+// Partially derives from a Java encoder, JpegEncoder.java by James R Weeks.
+// Implements Baseline JPEG Encoding http://www.opennet.ru/docs/formats/jpeg.txt
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace FluxJpeg.Core.Encoder
+{
+ public class JpegEncodeProgressChangedArgs : EventArgs
+ {
+ public double EncodeProgress; // 0.0 to 1.0
+ }
+
+ public class JpegEncoder
+ {
+ JpegEncodeProgressChangedArgs _progress;
+
+ DecodedJpeg _input;
+ Stream _outStream;
+ HuffmanTable _huf;
+ DCT _dct;
+
+ int _height;
+ int _width;
+ int _quality;
+
+ private const int Ss = 0;
+ private const int Se = 63;
+ private const int Ah = 0;
+ private const int Al = 0;
+
+ private static readonly int[] CompID = { 1, 2, 3 };
+ private static readonly int[] HsampFactor = { 1, 1, 1 };
+ private static readonly int[] VsampFactor = { 1, 1, 1 };
+ private static readonly int[] QtableNumber = { 0, 1, 1 };
+ private static readonly int[] DCtableNumber = { 0, 1, 1 };
+ private static readonly int[] ACtableNumber = { 0, 1, 1 };
+
+ public event EventHandler<JpegEncodeProgressChangedArgs> EncodeProgressChanged;
+
+ public JpegEncoder(Image image, int quality, Stream outStream)
+ : this(new DecodedJpeg(image), quality, outStream) { /* see overload */ }
+
+ /// <summary>
+ /// Encodes a JPEG, preserving the colorspace and metadata of the input JPEG.
+ /// </summary>
+ /// <param name="decodedJpeg">Decoded Jpeg to start with.</param>
+ /// <param name="quality">Quality of the image from 0 to 100. (Compression from max to min.)</param>
+ /// <param name="outStream">Stream where the result will be placed.</param>
+ public JpegEncoder(DecodedJpeg decodedJpeg, int quality, Stream outStream)
+ {
+ _input = decodedJpeg;
+
+ /* This encoder requires YCbCr */
+ _input.Image.ChangeColorSpace(ColorSpace.YCbCr);
+
+ _quality = quality;
+
+ _height = _input.Image.Height;
+ _width = _input.Image.Width;
+ _outStream = outStream;
+ _dct = new DCT(_quality);
+ _huf = new HuffmanTable(null);
+ }
+
+ public void Encode()
+ {
+ _progress = new JpegEncodeProgressChangedArgs();
+
+ WriteHeaders();
+ CompressTo(_outStream);
+ WriteMarker(new byte[] { 0xFF, 0xD9 }); // End of Image
+
+ _progress.EncodeProgress = 1.0;
+ if (EncodeProgressChanged != null)
+ EncodeProgressChanged(this, _progress);
+
+ _outStream.Flush();
+ }
+
+ internal void WriteHeaders()
+ {
+ int i, j, index, offset;
+ int[] tempArray;
+
+ // Start of Image
+ byte[] SOI = { (byte)0xFF, (byte)0xD8 };
+ WriteMarker(SOI);
+
+ if (!_input.HasJFIF) // Supplement JFIF if missing
+ {
+ byte[] JFIF = new byte[18]
+ {
+ (byte)0xff, (byte)0xe0,
+ (byte)0x00, (byte)0x10,
+ (byte)0x4a, (byte)0x46,
+ (byte)0x49, (byte)0x46,
+ (byte)0x00, (byte)0x01,
+ (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x01,
+ (byte)0x00, (byte)0x01,
+ (byte)0x00, (byte)0x00
+ };
+
+ WriteArray(JFIF);
+ }
+
+ IO.BinaryWriter writer = new IO.BinaryWriter(_outStream);
+
+ /* APP headers and COM headers follow the same format
+ * which has a 16-bit integer length followed by a block
+ * of binary data. */
+ foreach (JpegHeader header in _input.MetaHeaders)
+ {
+ writer.Write(JPEGMarker.XFF);
+ writer.Write(header.Marker);
+
+ // Header's length
+ writer.Write((short)(header.Data.Length + 2));
+ writer.Write(header.Data);
+ }
+
+ // The DQT header
+ // 0 is the luminance index and 1 is the chrominance index
+ byte[] DQT = new byte[134];
+ DQT[0] = JPEGMarker.XFF;
+ DQT[1] = JPEGMarker.DQT;
+ DQT[2] = (byte)0x00;
+ DQT[3] = (byte)0x84;
+ offset = 4;
+ for (i = 0; i < 2; i++)
+ {
+ DQT[offset++] = (byte)((0 << 4) + i);
+ tempArray = (int[])_dct.quantum[i];
+
+ for (j = 0; j < 64; j++)
+ {
+ DQT[offset++] = (byte)tempArray[ ZigZag.ZigZagMap[j] ];
+ }
+ }
+
+ WriteArray(DQT);
+
+ // Start of Frame Header ( Baseline JPEG )
+ byte[] SOF = new byte[19];
+ SOF[0] = JPEGMarker.XFF;
+ SOF[1] = JPEGMarker.SOF0;
+ SOF[2] = (byte)0x00;
+ SOF[3] = (byte)17;
+ SOF[4] = (byte)_input.Precision;
+ SOF[5] = (byte)((_input.Image.Height >> 8) & 0xFF);
+ SOF[6] = (byte)((_input.Image.Height) & 0xFF);
+ SOF[7] = (byte)((_input.Image.Width >> 8) & 0xFF);
+ SOF[8] = (byte)((_input.Image.Width) & 0xFF);
+ SOF[9] = (byte)_input.Image.ComponentCount;
+ index = 10;
+
+ for (i = 0; i < SOF[9]; i++)
+ {
+ SOF[index++] = (byte)JpegEncoder.CompID[i];
+ SOF[index++] = (byte)((_input.HsampFactor[i] << 4) + _input.VsampFactor[i]);
+ SOF[index++] = (byte)JpegEncoder.QtableNumber[i];
+ }
+
+ WriteArray(SOF);
+
+ // The DHT Header
+ byte[] DHT1, DHT2, DHT3, DHT4;
+ int bytes, temp, oldindex, intermediateindex;
+ index = 4;
+ oldindex = 4;
+ DHT1 = new byte[17];
+ DHT4 = new byte[4];
+ DHT4[0] = JPEGMarker.XFF;
+ DHT4[1] = JPEGMarker.DHT;
+ for (i = 0; i < 4; i++)
+ {
+ bytes = 0;
+
+ // top 4 bits: table class (0=DC, 1=AC)
+ // bottom 4: index (0=luminance, 1=chrominance)
+ byte huffmanInfo = (i == 0) ? (byte)0x00 :
+ (i == 1) ? (byte)0x10 :
+ (i == 2) ? (byte)0x01 : (byte)0x11;
+
+ DHT1[index++ - oldindex] = huffmanInfo;
+
+ for (j = 0; j < 16; j++)
+ {
+ temp = _huf.bitsList[i][j];
+ DHT1[index++ - oldindex] = (byte)temp;
+ bytes += temp;
+ }
+
+ intermediateindex = index;
+ DHT2 = new byte[bytes];
+ for (j = 0; j < bytes; j++)
+ {
+ DHT2[index++ - intermediateindex] = (byte)_huf.val[i][j];
+ }
+ DHT3 = new byte[index];
+ Array.Copy(DHT4, 0, DHT3, 0, oldindex);
+ Array.Copy(DHT1, 0, DHT3, oldindex, 17);
+ Array.Copy(DHT2, 0, DHT3, oldindex + 17, bytes);
+ DHT4 = DHT3;
+ oldindex = index;
+ }
+ DHT4[2] = (byte)(((index - 2) >> 8) & 0xFF);
+ DHT4[3] = (byte)((index - 2) & 0xFF);
+ WriteArray(DHT4);
+
+ // Start of Scan Header
+ byte[] SOS = new byte[14];
+ SOS[0] = JPEGMarker.XFF;
+ SOS[1] = JPEGMarker.SOS;
+ SOS[2] = (byte)0x00;
+ SOS[3] = (byte)12;
+ SOS[4] = (byte)_input.Image.ComponentCount;
+
+ index = 5;
+
+ for (i = 0; i < SOS[4]; i++)
+ {
+ SOS[index++] = (byte)JpegEncoder.CompID[i];
+ SOS[index++] = (byte)((JpegEncoder.DCtableNumber[i] << 4) + JpegEncoder.ACtableNumber[i]);
+ }
+
+ SOS[index++] = (byte)JpegEncoder.Ss;
+ SOS[index++] = (byte)JpegEncoder.Se;
+ SOS[index++] = (byte)((JpegEncoder.Ah << 4) + JpegEncoder.Al);
+ WriteArray(SOS);
+
+ }
+
+
+ internal void CompressTo(Stream outStream)
+ {
+ int i = 0, j = 0, r = 0, c = 0, a = 0, b = 0;
+ int comp, xpos, ypos, xblockoffset, yblockoffset;
+ byte[,] inputArray = null;
+ float[,] dctArray1 = new float[8, 8];
+ float[,] dctArray2 = new float[8, 8];
+ int[] dctArray3 = new int[8 * 8];
+
+ int[] lastDCvalue = new int[_input.Image.ComponentCount];
+
+ int Width = 0, Height = 0;
+ int MinBlockWidth, MinBlockHeight;
+
+ // This initial setting of MinBlockWidth and MinBlockHeight is done to
+ // ensure they start with values larger than will actually be the case.
+ MinBlockWidth = ((_width % 8 != 0) ? (int)(Math.Floor((double)_width / 8.0) + 1) * 8 : _width);
+ MinBlockHeight = ((_height % 8 != 0) ? (int)(Math.Floor((double)_height / 8.0) + 1) * 8 : _height);
+ for (comp = 0; comp < _input.Image.ComponentCount; comp++)
+ {
+ MinBlockWidth = Math.Min(MinBlockWidth, _input.BlockWidth[comp]);
+ MinBlockHeight = Math.Min(MinBlockHeight, _input.BlockHeight[comp]);
+ }
+ xpos = 0;
+
+ for (r = 0; r < MinBlockHeight; r++)
+ {
+ // Keep track of progress
+ _progress.EncodeProgress = (double)r / MinBlockHeight;
+ if (EncodeProgressChanged != null) EncodeProgressChanged(this, _progress);
+
+ for (c = 0; c < MinBlockWidth; c++)
+ {
+ xpos = c * 8;
+ ypos = r * 8;
+ for (comp = 0; comp < _input.Image.ComponentCount; comp++)
+ {
+ Width = _input.BlockWidth[comp];
+ Height = _input.BlockHeight[comp];
+
+ inputArray = _input.Image.Raster[comp];
+
+ for (i = 0; i < _input.VsampFactor[comp]; i++)
+ {
+ for (j = 0; j < _input.HsampFactor[comp]; j++)
+ {
+ xblockoffset = j * 8;
+ yblockoffset = i * 8;
+ for (a = 0; a < 8; a++)
+ {
+ // set Y value. check bounds
+ int y = ypos + yblockoffset + a; if (y >= _height) break;
+
+ for (b = 0; b < 8; b++)
+ {
+ int x = xpos + xblockoffset + b; if (x >= _width) break;
+ dctArray1[a, b] = inputArray[x,y];
+ }
+ }
+ dctArray2 = _dct.FastFDCT(dctArray1);
+ dctArray3 = _dct.QuantizeBlock(dctArray2, JpegEncoder.QtableNumber[comp]);
+
+ _huf.HuffmanBlockEncoder(outStream, dctArray3, lastDCvalue[comp], JpegEncoder.DCtableNumber[comp], JpegEncoder.ACtableNumber[comp]);
+ lastDCvalue[comp] = dctArray3[0];
+ }
+ }
+ }
+ }
+ }
+
+ _huf.FlushBuffer(outStream);
+ }
+
+
+ void WriteMarker(byte[] data)
+ {
+ _outStream.Write(data, 0, 2);
+ }
+
+ void WriteArray(byte[] data)
+ {
+ int length = (((int)(data[2] & 0xFF)) << 8) + (int)(data[3] & 0xFF) + 2;
+ _outStream.Write(data, 0, length);
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/FDCT.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/FDCT.cs
new file mode 100644
index 0000000..630ce88
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/FDCT.cs
@@ -0,0 +1,201 @@
+using System;
+
+namespace FluxJpeg.Core
+{
+ public partial class DCT
+ {
+ public const int N = 8;
+
+ public int[][] quantum = new int[2][];
+ public double[][] divisors = new double[2][];
+
+ // Quantitization Matrix for luminace.
+ public double[] DivisorsLuminance = new double[N * N];
+
+ // Quantitization Matrix for chrominance.
+ public double[] DivisorsChrominance = new double[N * N];
+
+ public DCT(int quality) : this()
+ {
+ Initialize(quality);
+ }
+
+ private void Initialize(int quality)
+ {
+ double[] aanScaleFactor =
+ {
+ 1.0, 1.387039845, 1.306562965, 1.175875602,
+ 1.0, 0.785694958, 0.541196100, 0.275899379
+ };
+
+ int i, j, index, Quality;
+
+ // jpeg_quality_scaling
+ if (quality <= 0) Quality = 1;
+ if (quality > 100) Quality = 100;
+ if (quality < 50) Quality = 5000 / quality;
+ else Quality = 200 - quality * 2;
+
+ int[] scaledLum = JpegQuantizationTable.K1Luminance
+ .getScaledInstance(Quality / 100f, true).Table;
+
+ index = 0;
+ for (i = 0; i < 8; i++)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ DivisorsLuminance[index] =
+ (double)1.0 /
+ ((double)scaledLum[index] * aanScaleFactor[i] * aanScaleFactor[j] * 8.0);
+
+ index++;
+ }
+ }
+
+ // Creating the chrominance matrix
+ int[] scaledChrom = JpegQuantizationTable.K2Chrominance
+ .getScaledInstance(Quality / 100f, true).Table;
+
+ index = 0;
+ for (i = 0; i < 8; i++)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ DivisorsChrominance[index] = (double)((double)1.0 / ((double)scaledChrom[index] * aanScaleFactor[i] * aanScaleFactor[j] * (double)8.0));
+ index++;
+ }
+ }
+
+ quantum[0] = scaledLum;
+ divisors[0] = DivisorsLuminance;
+ quantum[1] = scaledChrom;
+ divisors[1] = DivisorsChrominance;
+ }
+
+ internal float[,] FastFDCT(float[,] input)
+ {
+ float[,] output = new float[N, N];
+
+ float tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ float tmp10, tmp11, tmp12, tmp13;
+ float z1, z2, z3, z4, z5, z11, z13;
+ int i, j;
+
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++)
+ output[i, j] = input[i, j] - 128f;
+
+ // Pass 1: process rows.
+
+ for (i = 0; i < 8; i++)
+ {
+ tmp0 = output[i, 0] + output[i, 7];
+ tmp7 = output[i, 0] - output[i, 7];
+ tmp1 = output[i, 1] + output[i, 6];
+ tmp6 = output[i, 1] - output[i, 6];
+ tmp2 = output[i, 2] + output[i, 5];
+ tmp5 = output[i, 2] - output[i, 5];
+ tmp3 = output[i, 3] + output[i, 4];
+ tmp4 = output[i, 3] - output[i, 4];
+
+ // Even part
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ output[i, 0] = tmp10 + tmp11;
+ output[i, 4] = tmp10 - tmp11;
+
+ z1 = (tmp12 + tmp13) * (float)0.707106781;
+ output[i, 2] = tmp13 + z1;
+ output[i, 6] = tmp13 - z1;
+
+ // Odd part
+ tmp10 = tmp4 + tmp5;
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ // The rotator is modified from fig 4-8 to avoid extra negations.
+ z5 = (tmp10 - tmp12) * (float)0.382683433;
+ z2 = ((float)0.541196100) * tmp10 + z5;
+ z4 = ((float)1.306562965) * tmp12 + z5;
+ z3 = tmp11 * ((float)0.707106781);
+
+ z11 = tmp7 + z3;
+ z13 = tmp7 - z3;
+
+ output[i, 5] = z13 + z2;
+ output[i, 3] = z13 - z2;
+ output[i, 1] = z11 + z4;
+ output[i, 7] = z11 - z4;
+ }
+
+ // Pass 2: process columns
+
+ for (i = 0; i < 8; i++)
+ {
+ tmp0 = output[0, i] + output[7, i];
+ tmp7 = output[0, i] - output[7, i];
+ tmp1 = output[1, i] + output[6, i];
+ tmp6 = output[1, i] - output[6, i];
+ tmp2 = output[2, i] + output[5, i];
+ tmp5 = output[2, i] - output[5, i];
+ tmp3 = output[3, i] + output[4, i];
+ tmp4 = output[3, i] - output[4, i];
+
+ // Even part
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ output[0, i] = tmp10 + tmp11;
+ output[4, i] = tmp10 - tmp11;
+
+ z1 = (tmp12 + tmp13) * (float)0.707106781;
+ output[2, i] = tmp13 + z1;
+ output[6, i] = tmp13 - z1;
+
+ // Odd part
+ tmp10 = tmp4 + tmp5;
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ // The rotator is modified from fig 4-8 to avoid extra negations.
+ z5 = (tmp10 - tmp12) * (float)0.382683433;
+ z2 = ((float)0.541196100) * tmp10 + z5;
+ z4 = ((float)1.306562965) * tmp12 + z5;
+ z3 = tmp11 * ((float)0.707106781);
+
+ z11 = tmp7 + z3;
+ z13 = tmp7 - z3;
+
+ output[5, i] = z13 + z2;
+ output[3, i] = z13 - z2;
+ output[1, i] = z11 + z4;
+ output[7, i] = z11 - z4;
+ }
+
+ return output;
+ }
+
+
+ internal int[] QuantizeBlock(float[,] inputData, int code)
+ {
+ int[] result = new int[N * N];
+ int index = 0;
+
+ for (int i = 0; i < N; i++)
+ for (int j = 0; j < N; j++)
+ {
+ result[index] = (int)(Math.Round(inputData[i, j] * divisors[code][index]));
+ index++;
+ }
+
+ return result;
+ }
+
+
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/Convolution.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/Convolution.cs
new file mode 100644
index 0000000..9099e8c
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/Convolution.cs
@@ -0,0 +1,404 @@
+/// Copyright (c) 2009 Jeffrey Powers for Occipital Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+using System.Threading;
+
+using FluxJpeg.Core;
+
+namespace FluxJpeg.Core.Filtering
+{
+ public class Convolution
+ {
+
+ public static readonly Convolution Instance = new Convolution();
+
+ public GrayImage GaussianConv(GrayImage data, double std)
+ {
+ float[] filter = GaussianFilter(std);
+ return Conv2DSeparable(data, filter);
+ }
+
+ public float[] GaussianFilter(double std)
+ {
+ const double Precision = 0.01f;
+
+ double var = std * std;
+
+ double n = Math.Sqrt(-1 * var * Math.Log(Precision));
+ int half = (int)Math.Ceiling(n);
+
+ float[] filter = new float[half];
+
+ double sum = -1.0;
+ for (int i = 0; i < half; i++)
+ {
+ double val = Math.Exp(-0.5 * (i * i) / var);
+ filter[i] = (float)val;
+ sum += 2 * val;
+ }
+
+ /* Normalize */
+ for (int i = 0; i < half; i++)
+ filter[i] /= (float)sum;
+
+ return filter;
+
+ }
+
+ public GrayImage Conv2DSeparable(GrayImage data, float[] filter)
+ {
+ GrayImage pass1 = Filter1DSymmetric(data, filter, true);
+ GrayImage result = Filter1DSymmetric(pass1, filter, true);
+
+ return result;
+ }
+
+ private struct FilterJob
+ {
+ public float[] filter;
+ public int start;
+ public int end;
+ public GrayImage data;
+ public GrayImage result;
+ public int dataPtr;
+ public int destPtr;
+ }
+
+
+ /// <summary>
+ /// Filters an GrayImage with a 1D symmetric filter along the X-axis.
+ /// (This operation is multithreaded)
+ /// </summary>
+ /// <param name="data">GrayImage to be operated on</param>
+ /// <param name="filter">Filter to use (center tap plus right-hand-side)</param>
+ /// <param name="transpose">Transpose the result?</param>
+ /// <returns>Transposed, filtered GrayImage.</returns>
+ public GrayImage Filter1DSymmetric(GrayImage data, float[] filter, bool transpose)
+ {
+ GrayImage result = transpose ?
+ new GrayImage(data.Height, data.Width) :
+ new GrayImage(data.Width, data.Height);
+
+ int startY = 0;
+
+ int destPtr = transpose ? startY : (startY * result.Width);
+
+ FilterJob job
+ = new FilterJob
+ {
+ filter = filter,
+ data = data,
+ destPtr = destPtr,
+ result = result,
+ start = startY,
+ end = data.Height / 2
+ };
+
+ ParameterizedThreadStart del = transpose ?
+ new ParameterizedThreadStart(FilterPartSymmetricT) :
+ new ParameterizedThreadStart(FilterPartSymmetric);
+
+ Thread worker = new Thread(del);
+ worker.Start(job);
+
+ startY = data.Height / 2;
+ destPtr = transpose ? startY : (startY * result.Width);
+
+
+ job.start = startY;
+ job.destPtr = destPtr;
+ job.end = data.Height;
+
+ del((object)job); // Run the appropriate filter in this thread, too
+
+ worker.Join();
+
+
+ return result;
+ }
+
+
+ /// <summary>
+ /// Convolves part of an GrayImage with a 1D filter along the X-axis
+ /// and transposes it as well.
+ /// </summary>
+ /// <param name="filterJob">Filter operation details</param>
+ private void FilterPartSymmetricT(object filterJob)
+ {
+ FilterJob fj = (FilterJob)filterJob;
+
+
+ GrayImage data = fj.data;
+ float[] srcData = data.Scan0;
+ float[] filter = fj.filter;
+ GrayImage result = fj.result;
+
+ int pad = filter.Length - 1;
+
+ #region Filter and transpose
+ for (int y = fj.start; y < fj.end; y++)
+ {
+ int rowStart = y * data.Width;
+
+ int ptr = rowStart;
+
+ // Left checked region
+ for (int x = 0; x < pad; x++)
+ {
+ float pixel = srcData[ptr] * filter[0];
+
+ // Part of the filter that fits within the GrayImage
+ for (int i = 1; i < x + 1; i++)
+ pixel += (srcData[ptr + i] + srcData[ptr - i]) * filter[i];
+
+ // Part of the filter that falls off the left side
+ for (int i = x + 1; i < filter.Length; i++)
+ pixel += (srcData[ptr + i] + srcData[ptr + i]) * filter[i];
+
+ result[y, x] = pixel; ptr++;
+ }
+
+ // Unchecked region
+ for (int x = pad; x < data.Width - pad; x++)
+ {
+ float pixel = srcData[ptr] * filter[0];
+
+ for (int i = 1; i < filter.Length; i++)
+ pixel += (srcData[ptr + i] + srcData[ptr - i]) * filter[i];
+
+ result[y, x] = pixel; ptr++;
+ }
+
+ // Right checked region
+ for (int x = data.Width - pad; x < data.Width; x++)
+ {
+ float pixel = srcData[ptr] * filter[0];
+
+ // Part of the filter that fits within the GrayImage
+ for (int i = 1; i < (data.Width - x); i++)
+ pixel += (srcData[ptr + i] + srcData[ptr - i]) * filter[i];
+
+ // Part of the filter that falls off the right side
+ for (int i = (data.Width - x); i < filter.Length; i++)
+ pixel += (srcData[ptr - i] + srcData[ptr - i]) * filter[i];
+
+ result[y, x] = pixel; ptr++;
+ }
+ }
+ #endregion
+
+ }
+
+ /// <summary>
+ /// Convolves an GrayImage with a 1D filter along the X-axis.
+ /// </summary>
+ /// <param name="filterJob">Filter operation details</param>
+ private void FilterPartSymmetric(object filterJob)
+ {
+ FilterJob fj = (FilterJob)filterJob;
+
+ GrayImage data = fj.data;
+ float[] srcData = data.Scan0;
+ float[] filter = fj.filter;
+ GrayImage result = fj.result;
+ float[] resData = result.Scan0;
+
+ int pad = filter.Length - 1;
+
+ int destPtr = fj.destPtr;
+
+ #region Filter (no transpose)
+ for (int y = fj.start; y < fj.end; y++)
+ {
+ int rowStart = y * data.Width;
+
+ int ptr = fj.dataPtr + rowStart;
+
+ // Left checked region
+ for (int x = 0; x < pad; x++)
+ {
+ float pixel = srcData[ptr] * filter[0];
+
+ // Part of the filter that fits within the GrayImage
+ for (int i = 1; i < x + 1; i++)
+ pixel += (srcData[ptr + i] + srcData[ptr - i]) * filter[i];
+
+ // Part of the filter that falls off the left side
+ for (int i = x + 1; i < filter.Length; i++)
+ pixel += (srcData[ptr + i] + srcData[ptr + i]) * filter[i];
+
+ resData[destPtr++] = pixel; ptr++;
+ }
+
+ // Unchecked region
+ for (int x = pad; x < data.Width - pad; x++)
+ {
+ float pixel = srcData[ptr] * filter[0];
+
+ for (int i = 1; i < filter.Length; i++)
+ pixel += (srcData[ptr + i] + srcData[ptr - i]) * filter[i];
+
+ resData[destPtr++] = pixel; ptr++;
+ }
+
+ // Right checked region
+ for (int x = data.Width - pad; x < data.Width; x++)
+ {
+ float pixel = srcData[ptr] * filter[0];
+
+ // Part of the filter that fits within the GrayImage
+ for (int i = 0; i < (data.Width - x); i++)
+ pixel += (srcData[ptr + i] + srcData[ptr - i]) * filter[i];
+
+ // Part of the filter that falls off the right side
+ for (int i = (data.Width - x); i < filter.Length; i++)
+ pixel += (srcData[ptr + i] + srcData[ptr - i]) * filter[i];
+
+ resData[destPtr++] = pixel; ptr++;
+ }
+ }
+
+ #endregion
+
+ }
+
+
+
+ public GrayImage Conv2DSymmetric(GrayImage data, GrayImage opLR)
+ {
+ int xPad = opLR.Width - 1;
+ int yPad = opLR.Height - 1;
+
+ GrayImage padded = new GrayImage(data.Width + 2 * xPad, data.Height + 2 * yPad);
+
+ int dataIdx = 0;
+ for (int y = 0; y < data.Height; y++)
+ {
+ int rowStart = (y + yPad) * (data.Width + 2 * xPad) + xPad;
+ for (int x = 0; x < data.Width; x++)
+ {
+ padded.Scan0[rowStart + x] = data.Scan0[dataIdx];
+ dataIdx++;
+ }
+ }
+
+ return Conv2DSymm(padded, opLR);
+ }
+
+
+ /// <summary>
+ /// Convolves an GrayImage with a 2D-symmetric operator.
+ /// </summary>
+ /// <param name="data">Data to be convolved with the operator</param>
+ /// <param name="opUL">Lower-right quadrant of the operator.</param>
+ /// <returns></returns>
+ private GrayImage Conv2DSymm(GrayImage data, GrayImage opLR)
+ {
+ if (opLR.Width % 2 != 0 || opLR.Height % 2 != 0)
+ throw new ArgumentException("Operator must have an even number of rows and columns.");
+
+ int xPad = opLR.Width - 1;
+ int yPad = opLR.Height - 1;
+
+ GrayImage result = new GrayImage(data.Width - 2 * xPad, data.Height - 2 * yPad);
+
+ for (int y = yPad; y < data.Height - yPad; y++)
+ {
+ for (int x = xPad; x < data.Width - xPad; x++)
+ {
+ // Center pixel
+ float pixel = data[x, y] * opLR.Scan0[0];
+
+ // Vertical center
+ for (int op_y = 1; op_y < opLR.Height; op_y++)
+ pixel += (data[x, y + op_y] + data[x, y - op_y]) * opLR[0, op_y];
+
+ //Horizontal center
+ for (int op_x = 1; op_x < opLR.Width; op_x++)
+ pixel += (data[x + op_x, y] + data[x - op_x, y]) * opLR[op_x, 0];
+
+ //Quadrants
+ int opIdx = 1;
+
+ for (int op_y = 1; op_y < opLR.Height; op_y++)
+ {
+ int baseIdx1 = ((y + op_y) * data.Width) + x;
+ int baseIdx2 = ((y - op_y) * data.Width) + x;
+
+ // Loop unrolling can save 25% execution time here
+
+ for (int op_x = 1; op_x < opLR.Width; op_x++)
+ {
+ pixel += (data.Scan0[baseIdx1 + op_x] +
+ data.Scan0[baseIdx2 + op_x] +
+ data.Scan0[baseIdx1 - op_x] +
+ data.Scan0[baseIdx2 - op_x]) * opLR.Scan0[opIdx];
+
+ opIdx++;
+ }
+
+ opIdx++; // Skip 0th col on next row
+ }
+
+ result[x - xPad, y - yPad] = pixel;
+
+ } // loop over data x
+
+ } // loop over data y
+
+ return result;
+ }
+
+ /// <summary>
+ /// Vanilla 2D convolution. Not optimized.
+ /// </summary>
+ /// <param name="data"></param>
+ /// <param name="op"></param>
+ /// <returns></returns>
+ public GrayImage Conv2D(GrayImage data, GrayImage op)
+ {
+ GrayImage result = new GrayImage(data.Width, data.Height);
+
+ if (op.Width % 2 == 0 || op.Height % 2 == 0)
+ throw new ArgumentException("Operator must have an odd number of rows and columns.");
+
+ int x_offset = op.Width / 2;
+ int y_offset = op.Height / 2;
+
+ for (int y = 0; y < data.Height; y++)
+ {
+ for (int x = 0; x < data.Width; x++)
+ {
+ float pixel = 0;
+ float wt = 0;
+
+ for (int op_y = 0; op_y < op.Height; op_y++)
+ {
+ int d_y = y - y_offset + op_y;
+ if (d_y < 0 || d_y >= data.Height) continue;
+
+ for (int op_x = 0; op_x < op.Width; op_x++)
+ {
+ int d_x = x - x_offset + op_x;
+ if (d_x < 0 || d_x >= data.Width) continue;
+
+ float op_val = op[op_x, op_y];
+
+ /* Perform actual convolution */
+ wt += Math.Abs(op_val);
+ pixel += data[d_x, d_y] * op_val;
+ }
+ }
+
+ result[x, y] = pixel / wt;
+
+ } // loop over data x
+
+ } // loop over data y
+
+ return result;
+ }
+
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/FilterBase.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/FilterBase.cs
new file mode 100644
index 0000000..a3f4b3a
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/FilterBase.cs
@@ -0,0 +1,47 @@
+/// Copyright (c) 2008-09 Jeffrey Powers for Occipital Open Source.
+/// Under the MIT License, details: License.txt.
+
+namespace FluxJpeg.Core.Filtering
+{
+ using System;
+
+ public enum ResamplingFilters
+ {
+ NearestNeighbor,
+ LowpassAntiAlias
+ //Bicubic
+ }
+
+ public class FilterProgressEventArgs : EventArgs { public double Progress; }
+
+ internal abstract class Filter
+ {
+ protected int _newWidth, _newHeight;
+ protected byte[][,] _sourceData, _destinationData;
+ protected bool _color;
+
+ public event EventHandler<FilterProgressEventArgs> ProgressChanged;
+ FilterProgressEventArgs progressArgs = new FilterProgressEventArgs();
+
+ protected void UpdateProgress(double progress)
+ {
+ progressArgs.Progress = progress;
+ if (ProgressChanged != null) ProgressChanged(this, progressArgs);
+ }
+
+ public byte[][,] Apply( byte[][,] imageData, int newWidth, int newHeight )
+ {
+ _newHeight = newHeight;
+ _newWidth = newWidth;
+ _color = !(imageData.Length == 1);
+ _destinationData = Image.CreateRaster(newWidth, newHeight, imageData.Length);
+ _sourceData = imageData;
+
+ ApplyFilter();
+
+ return _destinationData;
+ }
+
+ protected abstract void ApplyFilter();
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/FilterLowpassResize.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/FilterLowpassResize.cs
new file mode 100644
index 0000000..e45004e
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/FilterLowpassResize.cs
@@ -0,0 +1,44 @@
+/// Copyright (c) 2009 Jeffrey Powers for Occipital Open Source.
+/// Under the MIT License, details: License.txt.
+
+namespace FluxJpeg.Core.Filtering
+{
+ using System;
+
+ internal class LowpassResize : Filter
+ {
+ protected override void ApplyFilter()
+ {
+ // get source image size
+ int width = _sourceData[0].GetLength(0),
+ height = _sourceData[0].GetLength(1);
+
+ int channels = _sourceData.Length;
+
+ // Estimate a good filter size for the gaussian.
+ // Note that gaussian isn't an ideal bandpass filter
+ // so this is an experimentally determined quantity
+ double std = (width / _newWidth) * 0.50;
+
+ for(int i = 0; i < channels; i++)
+ {
+ GrayImage channel = new GrayImage(_sourceData[i]);
+
+ channel = Convolution.Instance.GaussianConv(channel, std);
+
+ _sourceData[i] = channel.ToByteArray2D();
+ }
+
+ // number of pixels to shift in the original image
+ double xStep = (double)width / _newWidth,
+ yStep = (double)height / _newHeight;
+
+
+ NNResize resizer = new NNResize();
+
+ _destinationData = resizer.Apply(_sourceData, _newWidth, _newHeight);
+
+
+ }
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/FilterNNResize.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/FilterNNResize.cs
new file mode 100644
index 0000000..44e3ddb
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/FilterNNResize.cs
@@ -0,0 +1,47 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+namespace FluxJpeg.Core.Filtering
+{
+ using System;
+
+ internal class NNResize : Filter
+ {
+ protected override void ApplyFilter()
+ {
+ // get source image size
+ int width = _sourceData[0].GetLength(0),
+ height = _sourceData[0].GetLength(1);
+
+ // number of pixels to shift in the original image
+ double xStep = (double)width / _newWidth,
+ yStep = (double)height / _newHeight;
+
+ double sX = 0.5*xStep, sY = 0.5*yStep;
+ int i_sY, i_sX;
+
+ for (int y = 0; y < _newHeight; y++)
+ {
+ i_sY = (int)sY; sX = 0;
+
+ UpdateProgress((double)y / _newHeight);
+
+ for (int x = 0; x < _newWidth; x++)
+ {
+ i_sX = (int)sX;
+
+ _destinationData[0][x, y] = _sourceData[0][i_sX, i_sY];
+
+ if (_color) {
+
+ _destinationData[1][x, y] = _sourceData[1][i_sX, i_sY];
+ _destinationData[2][x, y] = _sourceData[2][i_sX, i_sY];
+ }
+
+ sX += xStep;
+ }
+ sY += yStep;
+ }
+ }
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/GrayImage.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/GrayImage.cs
new file mode 100644
index 0000000..0ea84e0
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Filter/GrayImage.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace FluxJpeg.Core.Filtering
+{
+ public class GrayImage
+ {
+ public float[] Scan0;
+ private int _width;
+ private int _height;
+
+ public int Width { get { return _width; } }
+ public int Height { get { return _height; } }
+
+ /// <summary>
+ /// Returns a new 0.0-initialized image of specified size.
+ /// </summary>
+ /// <param name="width">Width in pixels</param>
+ /// <param name="height">Height in pixels</param>
+ public GrayImage(int width, int height)
+ {
+ _width = width; _height = height;
+ Scan0 = new float[width * height];
+ }
+
+ /// <summary>
+ /// Creates a 0.0 to 1.0 grayscale image from a bitmap.
+ /// </summary>
+ public GrayImage(byte[,] channel)
+ {
+ Convert(channel);
+ }
+
+ /// <summary>
+ /// Access a pixel within the image.
+ /// </summary>
+ /// <param name="x">X-coordinate</param>
+ /// <param name="y">Y-coordinate</param>
+ /// <returns>Pixel brightness between 0.0 and 1.0</returns>
+ public float this[int x, int y]
+ {
+ get { return Scan0[y * _width + x]; }
+ set { Scan0[y * _width + x] = value; }
+ }
+
+ private void Convert(byte[,] channel)
+ {
+ _width = channel.GetLength(0);
+ _height = channel.GetLength(1);
+
+ Scan0 = new float[_width* _height];
+
+ int i = 0;
+
+ for (int y = 0; y < _height; y++)
+ for (int x = 0; x < _width; x++)
+ Scan0[i++] = channel[x, y] / 255f;
+ }
+
+ public byte[,] ToByteArray2D()
+ {
+ byte[,] result = new byte[_width, _height];
+
+ int i = 0;
+ for (int y = 0; y < _height; y++)
+ for (int x = 0; x < _width; x++)
+ result[x, y] = (byte)(Scan0[i++] * 255f);
+
+ return result;
+ }
+
+
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/IJG.txt b/debian/missing-sources/plupload/csharp/Plupload/FJCore/IJG.txt
new file mode 100644
index 0000000..08a1ed8
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/IJG.txt
@@ -0,0 +1,90 @@
+This software is based in part on the work of the Independent JPEG Group:
+
+The Independent JPEG Group's JPEG software
+==========================================
+
+LEGAL ISSUES
+============
+
+In plain English:
+
+1. We don't promise that this software works. (But if you find any bugs,
+ please let us know!)
+2. You can use this software for whatever you want. You don't have to pay us.
+3. You may not pretend that you wrote this software. If you use it in a
+ program, you must acknowledge somewhere in your documentation that
+ you've used the IJG code.
+
+In legalese:
+
+The authors make NO WARRANTY or representation, either express or implied,
+with respect to this software, its quality, accuracy, merchantability, or
+fitness for a particular purpose. This software is provided "AS IS", and you,
+its user, assume the entire risk as to its quality and accuracy.
+
+This software is copyright (C) 1991-1998, Thomas G. Lane.
+All Rights Reserved except as specified below.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+software (or portions thereof) for any purpose, without fee, subject to these
+conditions:
+(1) If any part of the source code for this software is distributed, then this
+README file must be included, with this copyright and no-warranty notice
+unaltered; and any additions, deletions, or changes to the original files
+must be clearly indicated in accompanying documentation.
+(2) If only executable code is distributed, then the accompanying
+documentation must state that "this software is based in part on the work of
+the Independent JPEG Group".
+(3) Permission for use of this software is granted only if the user accepts
+full responsibility for any undesirable consequences; the authors accept
+NO LIABILITY for damages of any kind.
+
+These conditions apply to any software derived from or based on the IJG code,
+not just to the unmodified library. If you use our work, you ought to
+acknowledge us.
+
+Permission is NOT granted for the use of any IJG author's name or company name
+in advertising or publicity relating to this software or products derived from
+it. This software may be referred to only as "the Independent JPEG Group's
+software".
+
+We specifically permit and encourage the use of this software as the basis of
+commercial products, provided that all warranty or liability claims are
+assumed by the product vendor.
+
+
+ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
+sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
+ansi2knr.c is NOT covered by the above copyright and conditions, but instead
+by the usual distribution terms of the Free Software Foundation; principally,
+that you must include source code if you redistribute it. (See the file
+ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part
+of any program generated from the IJG code, this does not limit you more than
+the foregoing paragraphs do.
+
+The Unix configuration script "configure" was produced with GNU Autoconf.
+It is copyright by the Free Software Foundation but is freely distributable.
+The same holds for its supporting scripts (config.guess, config.sub,
+ltconfig, ltmain.sh). Another support script, install-sh, is copyright
+by M.I.T. but is also freely distributable.
+
+It appears that the arithmetic coding option of the JPEG spec is covered by
+patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot
+legally be used without obtaining one or more licenses. For this reason,
+support for arithmetic coding has been removed from the free JPEG software.
+(Since arithmetic coding provides only a marginal gain over the unpatented
+Huffman mode, it is unlikely that very many implementations will support it.)
+So far as we are aware, there are no patent restrictions on the remaining
+code.
+
+The IJG distribution formerly included code to read and write GIF files.
+To avoid entanglement with the Unisys LZW patent, GIF reading support has
+been removed altogether, and the GIF writer has been simplified to produce
+"uncompressed GIFs". This technique does not use the LZW algorithm; the
+resulting GIF files are larger than usual, but are readable by all standard
+GIF decoders.
+
+We are required to state that
+ "The Graphics Interchange Format(c) is the Copyright property of
+ CompuServe Incorporated. GIF(sm) is a Service Mark property of
+ CompuServe Incorporated."
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/IO/BinaryReader.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/IO/BinaryReader.cs
new file mode 100644
index 0000000..70a0ee6
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/IO/BinaryReader.cs
@@ -0,0 +1,46 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+using System.IO;
+
+namespace FluxJpeg.Core.IO
+{
+ /// <summary>
+ /// Big-endian binary reader
+ /// </summary>
+ internal class BinaryReader
+ {
+ Stream _stream;
+ byte[] _buffer;
+
+ public Stream BaseStream { get { return _stream; } }
+
+ public BinaryReader(byte[] data) : this(new MemoryStream(data)) { }
+
+ public BinaryReader(Stream stream)
+ {
+ _stream = stream;
+ _buffer = new byte[2];
+ }
+
+ public byte ReadByte()
+ {
+ int b = _stream.ReadByte();
+ if (b == -1) throw new EndOfStreamException();
+ return (byte)b;
+ }
+
+ public ushort ReadShort()
+ {
+ _stream.Read(_buffer, 0, 2);
+ return (ushort)((_buffer[0] << 8) | (_buffer[1] & 0xff));
+ }
+
+ public int Read(byte[] buffer, int offset, int count)
+ {
+ return _stream.Read(buffer, offset, count);
+ }
+
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/IO/BinaryWriter.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/IO/BinaryWriter.cs
new file mode 100644
index 0000000..b9dc969
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/IO/BinaryWriter.cs
@@ -0,0 +1,45 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+using System.Text;
+using System.IO;
+
+namespace FluxJpeg.Core.IO
+{
+ /// <summary>
+ /// A Big-endian binary writer.
+ /// </summary>
+ internal class BinaryWriter
+ {
+ private Stream _stream;
+
+ internal BinaryWriter(Stream stream)
+ {
+ _stream = stream;
+ }
+
+ internal void Write(byte[] val)
+ {
+ _stream.Write(val, 0, val.Length);
+ }
+
+ internal void Write(byte[] val, int offset, int count)
+ {
+ _stream.Write(val, offset, count);
+ }
+
+
+ internal void Write(short val)
+ {
+ _stream.WriteByte((byte)(( val >> 8 ) & 0xFF));
+ _stream.WriteByte((byte)(val & 0xFF));
+ }
+
+ internal void Write(byte val)
+ {
+ _stream.WriteByte(val);
+ }
+
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/IO/JpegBinaryReader.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/IO/JpegBinaryReader.cs
new file mode 100644
index 0000000..759b248
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/IO/JpegBinaryReader.cs
@@ -0,0 +1,117 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+using System.IO;
+
+namespace FluxJpeg.Core.IO
+{
+ internal class JPEGMarkerFoundException : Exception
+ {
+ public JPEGMarkerFoundException(byte marker) { this.Marker = marker; }
+ public byte Marker;
+ }
+
+ internal class JPEGBinaryReader : IO.BinaryReader
+ {
+ public int eob_run = 0;
+
+ private byte marker;
+
+ public JPEGBinaryReader(Stream input)
+ : base(input)
+ {
+ }
+
+ /// <summary>
+ /// Seeks through the stream until a marker is found.
+ /// </summary>
+ public byte GetNextMarker()
+ {
+ try { while (true) { ReadJpegByte(); } }
+ catch (JPEGMarkerFoundException ex) {
+ return ex.Marker;
+ }
+ }
+
+ byte _bitBuffer;
+
+ protected int _bitsLeft = 0;
+
+ public int BitOffset
+ {
+ get { return (8 - _bitsLeft) % 8; }
+ set
+ {
+ if (_bitsLeft != 0) BaseStream.Seek(-1, SeekOrigin.Current);
+ _bitsLeft = (8 - value) % 8;
+ }
+ }
+
+ /// <summary>
+ /// Places n bits from the stream, where the most-significant bits
+ /// from the first byte read end up as the most-significant of the returned
+ /// n bits.
+ /// </summary>
+ /// <param name="n">Number of bits to return</param>
+ /// <returns>Integer containing the bits desired -- shifted all the way right.</returns>
+ public int ReadBits(int n)
+ {
+ int result = 0;
+
+ #region Special case -- included for optimization purposes
+ if (_bitsLeft >= n)
+ {
+ _bitsLeft-=n;
+ result = _bitBuffer >> (8 - n);
+ _bitBuffer = (byte)(_bitBuffer << n);
+ return result;
+ }
+ #endregion
+
+ while (n > 0)
+ {
+ if (_bitsLeft == 0)
+ {
+ _bitBuffer = ReadJpegByte();
+ _bitsLeft = 8;
+ }
+
+ int take = n <= _bitsLeft ? n : _bitsLeft;
+
+ result = result | ((_bitBuffer >> 8 - take) << (n - take));
+
+ _bitBuffer = (byte)(_bitBuffer << take);
+
+ _bitsLeft -= take;
+ n -= take;
+ }
+
+ return result;
+ }
+
+ protected byte ReadJpegByte()
+ {
+ byte c = ReadByte();
+
+ /* If it's 0xFF, check and discard stuffed zero byte */
+ if (c == JPEGMarker.XFF)
+ {
+ // Discard padded oxFFs
+ while ((c = ReadByte()) == 0xff) ;
+
+ // ff00 is the escaped form of 0xff
+ if (c == 0) c = 0xff;
+ else
+ {
+ // Otherwise we've found a new marker.
+ marker = c;
+ throw new JPEGMarkerFoundException(marker);
+ }
+ }
+
+ return c;
+ }
+
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Image.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Image.cs
new file mode 100644
index 0000000..d1db8cd
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Image.cs
@@ -0,0 +1,183 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+#if SILVERLIGHT
+#else
+using System.Drawing;
+using System.Drawing.Imaging;
+#endif
+
+namespace FluxJpeg.Core {
+ public struct ColorModel {
+ public ColorSpace colorspace;
+ public bool Opaque;
+ }
+
+ public enum ColorSpace { Gray, YCbCr, RGB }
+
+ public class Image {
+ private ColorModel _cm;
+ private byte[][,] _raster;
+
+ public byte[][,] Raster { get { return _raster; } }
+ public ColorModel ColorModel { get { return _cm; } }
+
+ /// <summary> X density (dots per inch).</summary>
+ public double DensityX { get; set; }
+ /// <summary> Y density (dots per inch).</summary>
+ public double DensityY { get; set; }
+
+ public int ComponentCount { get { return _raster.Length; } }
+
+ /// <summary>
+ /// Converts the colorspace of an image (in-place)
+ /// </summary>
+ /// <param name="cs">Colorspace to convert into</param>
+ /// <returns>Self</returns>
+ public Image ChangeColorSpace(ColorSpace cs) {
+ // Colorspace is already correct
+ if (_cm.colorspace == cs) return this;
+
+ byte[] ycbcr = new byte[3];
+ byte[] rgb = new byte[3];
+
+ if (_cm.colorspace == ColorSpace.RGB && cs == ColorSpace.YCbCr) {
+ /*
+ * Y' = + 0.299 * R'd + 0.587 * G'd + 0.114 * B'd
+ Cb = 128 - 0.168736 * R'd - 0.331264 * G'd + 0.5 * B'd
+ Cr = 128 + 0.5 * R'd - 0.418688 * G'd - 0.081312 * B'd
+ *
+ */
+
+ for (int x = 0; x < width; x++)
+ for (int y = 0; y < height; y++) {
+ YCbCr.fromRGB(ref _raster[0][x, y], ref _raster[1][x, y], ref _raster[2][x, y]);
+ }
+
+ _cm.colorspace = ColorSpace.YCbCr;
+
+
+ } else if (_cm.colorspace == ColorSpace.YCbCr && cs == ColorSpace.RGB) {
+
+ for (int x = 0; x < width; x++)
+ for (int y = 0; y < height; y++) {
+ // 0 is LUMA
+ // 1 is BLUE
+ // 2 is RED
+
+ YCbCr.toRGB(ref _raster[0][x, y], ref _raster[1][x, y], ref _raster[2][x, y]);
+ }
+
+ _cm.colorspace = ColorSpace.RGB;
+ } else if (_cm.colorspace == ColorSpace.Gray && cs == ColorSpace.YCbCr) {
+ // To convert to YCbCr, we just add two 128-filled chroma channels
+
+ byte[,] Cb = new byte[width, height];
+ byte[,] Cr = new byte[width, height];
+
+ for (int x = 0; x < width; x++)
+ for (int y = 0; y < height; y++) {
+ Cb[x, y] = 128; Cr[x, y] = 128;
+ }
+
+ _raster = new byte[][,] { _raster[0], Cb, Cr };
+
+ _cm.colorspace = ColorSpace.YCbCr;
+ } else if (_cm.colorspace == ColorSpace.Gray && cs == ColorSpace.RGB) {
+ ChangeColorSpace(ColorSpace.YCbCr);
+ ChangeColorSpace(ColorSpace.RGB);
+ } else {
+ throw new Exception("Colorspace conversion not supported.");
+ }
+
+ return this;
+ }
+
+ private int width; private int height;
+
+ public int Width { get { return width; } }
+ public int Height { get { return height; } }
+
+ public Image(ColorModel cm, byte[][,] raster) {
+ width = raster[0].GetLength(0);
+ height = raster[0].GetLength(1);
+
+ _cm = cm;
+ _raster = raster;
+ }
+
+ public static byte[][,] CreateRaster(int width, int height, int bands) {
+ // Create the raster
+ byte[][,] raster = new byte[bands][,];
+ for (int b = 0; b < bands; b++)
+ raster[b] = new byte[width, height];
+ return raster;
+ }
+
+ delegate void ConvertColor(ref byte c1, ref byte c2, ref byte c3);
+
+#if SILVERLIGHT
+#else
+ public Bitmap ToBitmap()
+ {
+ ConvertColor ColorConverter;
+
+ switch(_cm.colorspace)
+ {
+ case ColorSpace.YCbCr:
+ ColorConverter = YCbCr.toRGB;
+ break;
+ default:
+ throw new Exception("Colorspace not supported yet.");
+ }
+
+ int _width = width;
+ int _height = height;
+
+ Bitmap bitmap = new Bitmap(_width, _height, PixelFormat.Format32bppArgb);
+
+ BitmapData bmData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
+ System.Drawing.Imaging.ImageLockMode.WriteOnly,
+ System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+
+ byte[] outColor = new byte[3];
+ byte[] inColor = new byte[3];
+
+ unsafe
+ {
+ int i = 0;
+
+ byte* ptrBitmap = (byte*)bmData.Scan0;
+
+ for (int y = 0; y < _height; y++)
+ {
+ for (int x = 0; x < _width; x++)
+ {
+ ptrBitmap[0] = (byte)_raster[0][x, y];
+ ptrBitmap[1] = (byte)_raster[1][x, y];
+ ptrBitmap[2] = (byte)_raster[2][x, y];
+
+ ColorConverter(ref ptrBitmap[0], ref ptrBitmap[1], ref ptrBitmap[2]);
+
+ // Swap RGB --> BGR
+ byte R = ptrBitmap[0];
+ ptrBitmap[0] = ptrBitmap[2];
+ ptrBitmap[2] = R;
+
+ ptrBitmap[3] = 255; /* 100% opacity */
+ ptrBitmap += 4; // advance to the next pixel
+ i++; // "
+ }
+ }
+ }
+
+ bitmap.UnlockBits(bmData);
+
+ return bitmap;
+
+ }
+#endif
+
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/JAI.txt b/debian/missing-sources/plupload/csharp/Plupload/FJCore/JAI.txt
new file mode 100644
index 0000000..999e4de
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/JAI.txt
@@ -0,0 +1,40 @@
+This software is based in part on the Java Advanced Imaging IO by Sun Microsystems.
+
+That software is governed by the following license:
+===================================================
+
+Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+- Redistribution of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+- Redistribution in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+Neither the name of Sun Microsystems, Inc. or the names of
+contributors may be used to endorse or promote products derived
+from this software without specific prior written permission.
+
+This software is provided "AS IS," without a warranty of any
+kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+You acknowledge that this software is not designed or intended for
+use in the design, construction, operation or maintenance of any
+nuclear facility. \ No newline at end of file
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/JpegMarker.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/JpegMarker.cs
new file mode 100644
index 0000000..2d18b0a
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/JpegMarker.cs
@@ -0,0 +1,128 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+
+namespace FluxJpeg.Core
+{
+ internal sealed class JPEGMarker
+ {
+ // JFIF identifiers
+ public const byte JFIF_J = (byte)0x4a;
+ public const byte JFIF_F = (byte)0x46;
+ public const byte JFIF_I = (byte)0x49;
+ public const byte JFIF_X = (byte)0x46;
+
+ // JFIF extension codes
+ public const byte JFXX_JPEG = (byte)0x10;
+ public const byte JFXX_ONE_BPP = (byte)0x11;
+ public const byte JFXX_THREE_BPP = (byte)0x13;
+
+ // Marker prefix. Next byte is a marker, unless ...
+ public const byte XFF = (byte)0xff;
+ // ... marker byte encoding an xff.
+ public const byte X00 = (byte)0x00;
+
+ #region Section Markers
+
+ /// <summary>Huffman Table</summary>
+ public const byte DHT = (byte)0xc4;
+
+ /// <summary>Quantization Table</summary>
+ public const byte DQT = (byte)0xdb;
+
+ /// <summary>Start of Scan</summary>
+ public const byte SOS = (byte)0xda;
+
+ /// <summary>Define Restart Interval</summary>
+ public const byte DRI = (byte)0xdd;
+
+ /// <summary>Comment</summary>
+ public const byte COM = (byte)0xfe;
+
+ /// <summary>Start of Image</summary>
+ public const byte SOI = (byte)0xd8;
+
+ /// <summary>End of Image</summary>
+ public const byte EOI = (byte)0xd9;
+
+ /// <summary>Define Number of Lines</summary>
+ public const byte DNL = (byte)0xdc;
+
+ #endregion
+
+ #region Application Reserved Keywords
+
+ public const byte APP0 = (byte)0xe0;
+ public const byte APP1 = (byte)0xe1;
+ public const byte APP2 = (byte)0xe2;
+ public const byte APP3 = (byte)0xe3;
+ public const byte APP4 = (byte)0xe4;
+ public const byte APP5 = (byte)0xe5;
+ public const byte APP6 = (byte)0xe6;
+ public const byte APP7 = (byte)0xe7;
+ public const byte APP8 = (byte)0xe8;
+ public const byte APP9 = (byte)0xe9;
+ public const byte APP10 = (byte)0xea;
+ public const byte APP11 = (byte)0xeb;
+ public const byte APP12 = (byte)0xec;
+ public const byte APP13 = (byte)0xed;
+ public const byte APP14 = (byte)0xee;
+ public const byte APP15 = (byte)0xef;
+
+ #endregion
+
+ public const byte RST0 = (byte)0xd0;
+ public const byte RST1 = (byte)0xd1;
+ public const byte RST2 = (byte)0xd2;
+ public const byte RST3 = (byte)0xd3;
+ public const byte RST4 = (byte)0xd4;
+ public const byte RST5 = (byte)0xd5;
+ public const byte RST6 = (byte)0xd6;
+ public const byte RST7 = (byte)0xd7;
+
+ #region Start of Frame (SOF)
+
+ /// <summary>Nondifferential Huffman-coding frame (baseline dct)</summary>
+ public const byte SOF0 = (byte)0xc0;
+
+ /// <summary>Nondifferential Huffman-coding frame (extended dct)</summary>
+ public const byte SOF1 = (byte)0xc1;
+
+ /// <summary>Nondifferential Huffman-coding frame (progressive dct)</summary>
+ public const byte SOF2 = (byte)0xc2;
+
+ /// <summary>Nondifferential Huffman-coding frame Lossless (Sequential)</summary>
+ public const byte SOF3 = (byte)0xc3;
+
+ /// <summary>Differential Huffman-coding frame Sequential DCT</summary>
+ public const byte SOF5 = (byte)0xc5;
+
+ /// <summary>Differential Huffman-coding frame Progressive DCT</summary>
+ public const byte SOF6 = (byte)0xc6;
+
+ /// <summary>Differential Huffman-coding frame lossless</summary>
+ public const byte SOF7 = (byte)0xc7;
+
+ /// <summary>Nondifferential Arithmetic-coding frame (extended dct)</summary>
+ public const byte SOF9 = (byte)0xc9;
+
+ /// <summary>Nondifferential Arithmetic-coding frame (progressive dct)</summary>
+ public const byte SOF10 = (byte)0xca;
+
+ /// <summary>Nondifferential Arithmetic-coding frame (lossless)</summary>
+ public const byte SOF11 = (byte)0xcb;
+
+ /// <summary>Differential Arithmetic-coding frame (sequential dct)</summary>
+ public const byte SOF13 = (byte)0xcd;
+
+ /// <summary>Differential Arithmetic-coding frame (progressive dct)</summary>
+ public const byte SOF14 = (byte)0xce;
+
+ /// <summary>Differential Arithmetic-coding frame (lossless)</summary>
+ public const byte SOF15 = (byte)0xcf;
+
+ #endregion
+
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/License.txt b/debian/missing-sources/plupload/csharp/Plupload/FJCore/License.txt
new file mode 100644
index 0000000..99cc648
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/License.txt
@@ -0,0 +1,24 @@
+Copyright (c) 2008-2009 Occipital Open Source
+
+Partial derivations: See IJG.txt and JAI.txt.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/README.txt b/debian/missing-sources/plupload/csharp/Plupload/FJCore/README.txt
new file mode 100644
index 0000000..7069e9e
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/README.txt
@@ -0,0 +1,30 @@
+FJCore: A Fluxcapacity Open Source Project
+--------------------------------------------------------------------------------------------
+
+Thanks for checking out FJCore, an image library including a pure C# implementation
+of the JPEG baseline and progressive codecs.
+
+Design goals:
+ - No external dependencies (besides a C# compiler and ECMA-standard CIL runtime)
+ - High performance
+ - High image quality
+ - Simple, intuitive usage pattern
+
+With your help, we can make this one of the most readable and efficient libraries
+available to run on any CIL runtime (including the .NET framework, Mono, and Silverlight)!
+
+Try FJCore online: fluxtools.net/emailphotos
+
+More information: fluxcapacity.net/open-source
+
+--------------------------------------------------------------------------------------------
+
+April 7, 2008:
+
+- Initial release.
+
+July 13, 2008:
+
+- Encoder is now included.
+- Silverlight project added (both FJCore and FJCoreWin share source).
+- FJExample, a Silverlight test application, is included. \ No newline at end of file
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/Resize/ImageResizer.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Resize/ImageResizer.cs
new file mode 100644
index 0000000..3a896b5
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/Resize/ImageResizer.cs
@@ -0,0 +1,98 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using FluxJpeg.Core.Filtering;
+
+namespace FluxJpeg.Core
+{
+ public class ResizeNotNeededException : Exception { }
+ public class ResizeProgressChangedEventArgs : EventArgs { public double Progress; }
+
+ public class ImageResizer
+ {
+ private ResizeProgressChangedEventArgs progress = new ResizeProgressChangedEventArgs();
+ public event EventHandler<ResizeProgressChangedEventArgs> ProgressChanged;
+
+ private Image _input;
+
+ public ImageResizer(Image input)
+ {
+ _input = input;
+ }
+
+ public static bool ResizeNeeded(FluxJpeg.Core.Image image, int maxEdgeLength)
+ {
+ double scale = (image.Width > image.Height) ?
+ (double)maxEdgeLength / image.Width :
+ (double)maxEdgeLength / image.Height;
+
+ return scale < 1.0; // true if we must downscale
+ }
+
+ public Image Resize(int maxEdgeLength, ResamplingFilters technique)
+ {
+ double scale = 0;
+
+ if (_input.Width > _input.Height)
+ scale = (double)maxEdgeLength / _input.Width;
+ else
+ scale = (double)maxEdgeLength / _input.Height;
+
+ if (scale >= 1.0)
+ throw new ResizeNotNeededException();
+ else
+ return Resize(scale, technique);
+ }
+
+ public Image Resize(int maxWidth, int maxHeight, ResamplingFilters technique)
+ {
+ double wFrac = (double)maxWidth / _input.Width;
+ double hFrac = (double)maxHeight / _input.Height;
+ double scale = 0;
+
+ // Make the image as large as possible, while
+ // fitting in the supplied box and
+ // obeying the aspect ratio
+
+ if (wFrac < hFrac) { scale = wFrac; }
+ else { scale = hFrac; }
+
+ if (scale >= 1.0)
+ throw new ResizeNotNeededException();
+ else
+ return Resize(scale, technique);
+ }
+
+ public Image Resize(double scale, ResamplingFilters technique)
+ {
+ int height = (int)(scale * _input.Height);
+ int width = (int)(scale * _input.Width);
+
+ Filter resizeFilter;
+
+ switch (technique)
+ {
+ case ResamplingFilters.NearestNeighbor:
+ resizeFilter = new NNResize();
+ break;
+ case ResamplingFilters.LowpassAntiAlias:
+ resizeFilter = new LowpassResize();
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+
+ return new Image(_input.ColorModel, resizeFilter.Apply(_input.Raster, width, height));
+ }
+
+ void ResizeProgressChanged(object sender, Filtering.FilterProgressEventArgs e)
+ {
+ progress.Progress = e.Progress;
+ if (ProgressChanged != null) ProgressChanged(this, progress);
+ }
+
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/YCbCr.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/YCbCr.cs
new file mode 100644
index 0000000..3128b36
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/YCbCr.cs
@@ -0,0 +1,59 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+using System;
+
+namespace FluxJpeg.Core
+{
+ internal class YCbCr
+ {
+
+ public static void toRGB(ref byte c1, ref byte c2, ref byte c3)
+ {
+ double dY = (double)c1;
+ double dCb2 = (double)c2 - 128;
+ double dCr2 = (double)c3 - 128;
+
+ double dR = dY + 1.402 * dCr2;
+ double dG = dY - 0.34414 * dCb2 - 0.71414 * dCr2;
+ double dB = dY + 1.772 * dCb2;
+
+ c1 = dR > 255 ? (byte)255 : dR < 0 ? (byte)0 : (byte)dR;
+ c2 = dG > 255 ? (byte)255 : dG < 0 ? (byte)0 : (byte)dG;
+ c3 = dB > 255 ? (byte)255 : dB < 0 ? (byte)0 : (byte)dB;
+ }
+
+ public static void fromRGB(ref byte c1, ref byte c2, ref byte c3)
+ {
+ double dR = (double)c1;
+ double dG = (double)c2;
+ double dB = (double)c3;
+
+ c1 = (byte)(0.299 * dR + 0.587 * dG + 0.114 * dB);
+ c2 = (byte)(-0.16874 * dR - 0.33126 * dG + 0.5 * dB + 128);
+ c3 = (byte)(0.5 * dR - 0.41869 * dG - 0.08131 * dB + 128);
+ }
+
+ ///* RGB to YCbCr range 0-255 */
+ //public static void fromRGB(byte[] rgb, byte[] ycbcr)
+ //{
+ // ycbcr[0] = (byte)((0.299 * (float)rgb[0] + 0.587 * (float)rgb[1] + 0.114 * (float)rgb[2]));
+ // ycbcr[1] = (byte)(128 + (byte)((-0.16874 * (float)rgb[0] - 0.33126 * (float)rgb[1] + 0.5 * (float)rgb[2])));
+ // ycbcr[2] = (byte)(128 + (byte)((0.5 * (float)rgb[0] - 0.41869 * (float)rgb[1] - 0.08131 * (float)rgb[2])));
+ //}
+
+
+ /* RGB to YCbCr range 0-255 */
+ public static float[] fromRGB(float[] data)
+ {
+ float[] dest = new float[3];
+
+ dest[0] = (float)((0.299 * (float)data[0] + 0.587 * (float)data[1] + 0.114 * (float)data[2]));
+ dest[1] = 128 + (float)((-0.16874 * (float)data[0] - 0.33126 * (float)data[1] + 0.5 * (float)data[2]));
+ dest[2] = 128 + (float)((0.5 * (float)data[0] - 0.41869 * (float)data[1] - 0.08131 * (float)data[2]));
+
+ return (dest);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FJCore/ZigZag.cs b/debian/missing-sources/plupload/csharp/Plupload/FJCore/ZigZag.cs
new file mode 100644
index 0000000..0dd7ac0
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FJCore/ZigZag.cs
@@ -0,0 +1,65 @@
+/// Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source.
+/// Under the MIT License, details: License.txt.
+
+namespace FluxJpeg.Core
+{
+ internal class ZigZag
+ {
+
+ #region Alternate Form
+ internal static readonly int[] ZigZagMap =
+ {
+ 0, 1, 8, 16, 9, 2, 3, 10,
+ 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63
+ };
+ //public static void UnZigZag(float[] input, float[] output)
+ //{
+ // for (int i = 0; i < 64; i++)
+ // output[ZigZagMap[i] / 8, ZigZagMap[i] % 8] = input[i];
+ //}
+ #endregion
+
+ public static void UnZigZag(float[] input, float[] output)
+ {
+ output[0] = input[0]; output[1] = input[1];
+ output[8] = input[2]; output[16] = input[3];
+ output[9] = input[4]; output[2] = input[5];
+ output[3] = input[6]; output[10] = input[7];
+ output[17] = input[8]; output[24] = input[9];
+ output[32] = input[10]; output[25] = input[11];
+ output[18] = input[12]; output[11] = input[13];
+ output[4] = input[14]; output[5] = input[15];
+ output[12] = input[16]; output[19] = input[17];
+ output[26] = input[18]; output[33] = input[19];
+ output[40] = input[20]; output[48] = input[21];
+ output[41] = input[22]; output[34] = input[23];
+ output[27] = input[24]; output[20] = input[25];
+ output[13] = input[26]; output[6] = input[27];
+ output[7] = input[28]; output[14] = input[29];
+ output[21] = input[30]; output[28] = input[31];
+ output[35] = input[32]; output[42] = input[33];
+ output[49] = input[34]; output[56] = input[35];
+ output[57] = input[36]; output[50] = input[37];
+ output[43] = input[38]; output[36] = input[39];
+ output[29] = input[40]; output[22] = input[41];
+ output[15] = input[42]; output[23] = input[43];
+ output[30] = input[44]; output[37] = input[45];
+ output[44] = input[46]; output[51] = input[47];
+ output[58] = input[48]; output[59] = input[49];
+ output[52] = input[50]; output[45] = input[51];
+ output[38] = input[52]; output[31] = input[53];
+ output[39] = input[54]; output[46] = input[55];
+ output[53] = input[56]; output[60] = input[57];
+ output[61] = input[58]; output[54] = input[59];
+ output[47] = input[60]; output[55] = input[61];
+ output[62] = input[62]; output[63] = input[63];
+ }
+
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/FileReference.cs b/debian/missing-sources/plupload/csharp/Plupload/FileReference.cs
new file mode 100644
index 0000000..4ba86a9
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/FileReference.cs
@@ -0,0 +1,721 @@
+/**
+ * FileReference.cs
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+using System;
+using System.IO;
+using System.Threading;
+using System.Windows.Threading;
+using System.Net;
+using System.Text.RegularExpressions;
+using System.Windows.Browser;
+using System.Windows.Media.Imaging;
+using System.Collections.Generic;
+using FluxJpeg.Core.Encoder;
+using FluxJpeg.Core;
+using Plupload.PngEncoder;
+
+namespace Moxiecode.Plupload {
+ enum ImageType {
+ Jpeg,
+ Png
+ }
+
+ /// <summary>
+ /// Description of File.
+ /// </summary>
+ public class FileReference {
+ #region private fields
+ private string name, uploadUrl, id, targetName, mimeType;
+ private FileInfo info;
+ private SynchronizationContext syncContext;
+ private int chunks, chunkSize;
+ private bool multipart, chunking;
+ private long size, chunk;
+ private string fileDataName;
+ private Dictionary<string, object> multipartParams;
+ private Dictionary<string, object> headers;
+ private Stream fileStream;
+ private Stream imageStream;
+ private HttpWebRequest req;
+ #endregion
+
+ /// <summary>Upload complete delegate.</summary>
+ public delegate void UploadCompleteHandler(object sender, UploadEventArgs e);
+
+ /// <summary>Upload chunk compleate delegate.</summary>
+ public delegate void UploadChunkCompleteHandler(object sender, UploadEventArgs e);
+
+ /// <summary>Upload error delegate.</summary>
+ public delegate void ErrorHandler(object sender, ErrorEventArgs e);
+
+ /// <summary>Upload progress delegate.</summary>
+ public delegate void ProgressHandler(object sender, ProgressEventArgs e);
+
+ /// <summary>Upload complete event</summary>
+ public event UploadCompleteHandler UploadComplete;
+
+ /// <summary>Upload chunk complete event</summary>
+ public event UploadChunkCompleteHandler UploadChunkComplete;
+
+ /// <summary>Error event</summary>
+ public event ErrorHandler Error;
+
+ /// <summary>Progress event</summary>
+ public event ProgressHandler Progress;
+
+ /// <summary>
+ /// Main constructor for the file reference.
+ /// </summary>
+ /// <param name="id">Unique file id for item.</param>
+ /// <param name="info">FileInfo that got returned from a file selection.</param>
+ public FileReference(string id, FileInfo info) {
+ this.id = id;
+ this.name = info.Name;
+ this.info = info;
+ this.size = info.Length;
+ }
+
+ /// <summary>Unique id for the file reference.</summary>
+ public string Id {
+ get { return id; }
+ }
+
+ /// <summary>File name to use with upload.</summary>
+ public string Name {
+ get { return name; }
+ set { name = value; }
+ }
+
+ /// <summary>File size for the selected file.</summary>
+ public long Size {
+ get { return this.size; }
+ }
+
+ /// <summary>
+ /// Uploads the file to the specific url and using the specified chunk_size.
+ /// </summary>
+ /// <param name="upload_url">URL to upload to.</param>
+ /// <param name="chunk_size">Chunk size to use.</param>
+ /// <param name="image_width">Image width to scale to.</param>
+ /// <param name="image_height">Image height to scale to.</param>
+ /// <param name="image_quality">Image quality to store as.</param>
+ public void Upload(string upload_url, string json_settings) {
+ int chunkSize = 0, imageWidth = 0, imageHeight = 0, imageQuality = 90;
+
+ Dictionary<string, object> settings = (Dictionary<string, object>) Moxiecode.Plupload.Utils.JsonReader.ParseJson(json_settings);
+
+ chunkSize = Convert.ToInt32(settings["chunk_size"]);
+ imageWidth = Convert.ToInt32(settings["image_width"]);
+ imageHeight = Convert.ToInt32(settings["image_height"]);
+ imageQuality = Convert.ToInt32(settings["image_quality"]);
+
+ this.fileDataName = (string)settings["file_data_name"];
+ this.multipart = Convert.ToBoolean(settings["multipart"]);
+ this.multipartParams = (Dictionary<string, object>)settings["multipart_params"];
+ this.headers = (Dictionary<string, object>)settings["headers"];
+ this.targetName = (string) settings["name"];
+ this.mimeType = (string) settings["mime"];
+
+ this.chunk = 0;
+ this.chunking = chunkSize > 0;
+
+ this.uploadUrl = upload_url;
+
+ try {
+ // Is jpeg and image size is defined
+ if (Regex.IsMatch(this.name, @"\.(jpeg|jpg|png)$", RegexOptions.IgnoreCase) && (imageWidth != 0 || imageHeight != 0 || imageQuality != 0))
+ {
+ if (Regex.IsMatch(this.name, @"\.png$"))
+ this.imageStream = this.ResizeImage(this.info.OpenRead(), imageWidth, imageHeight, imageQuality, ImageType.Png);
+ else
+ this.imageStream = this.ResizeImage(this.info.OpenRead(), imageWidth, imageHeight, imageQuality, ImageType.Jpeg);
+
+ this.imageStream.Seek(0, SeekOrigin.Begin);
+ this.size = this.imageStream.Length;
+ }
+ } catch (Exception ex) {
+ syncContext.Send(delegate {
+ this.OnIOError(new ErrorEventArgs(ex.Message, 0, this.chunks));
+ }, this);
+ }
+
+ if (this.chunking) {
+ this.chunkSize = chunkSize;
+ this.chunks = (int) Math.Ceiling((double) this.Size / (double) chunkSize);
+ } else {
+ this.chunkSize = (int) this.Size;
+ this.chunks = 1;
+ }
+
+ this.UploadNextChunk();
+ }
+
+ private int ReadByteRange(byte[] buffer, long position, int offset, int count) {
+ int bytes = -1;
+
+ // Read from image memory stream if it's defined
+ if (this.imageStream != null) {
+ this.imageStream.Seek(position, SeekOrigin.Begin);
+ return this.imageStream.Read(buffer, offset, count);
+ }
+
+ // Open the file and read the specified part of it
+ if (this.fileStream == null) {
+ this.fileStream = this.info.OpenRead();
+ }
+
+ bytes = this.fileStream.Read(buffer, offset, count);
+
+ return bytes;
+ }
+
+ /// <summary>
+ /// Uploads the next chunk if there are more in queue.
+ /// </summary>
+ /// <returns>True/false if there are more chunks to be uploaded.</returns>
+ public bool UploadNextChunk() {
+ string url = this.uploadUrl;
+
+ // Is there more chunks
+ if (this.chunk >= this.chunks)
+ return false;
+
+ this.syncContext = SynchronizationContext.Current;
+
+ // Add name, chunk and chunks to query string when we don't use multipart
+ if (!this.multipart) {
+ if (url.IndexOf('?') == -1) {
+ url += '?';
+ } else {
+ url += '&';
+ }
+
+ url += "name=" + Uri.EscapeDataString(this.targetName);
+
+ if (this.chunking) {
+ url += "&chunk=" + this.chunk;
+ url += "&chunks=" + this.chunks;
+ }
+ }
+
+ this.req = WebRequest.Create(new Uri(HtmlPage.Document.DocumentUri, url)) as HttpWebRequest;
+ this.req.Method = "POST";
+
+ // Add custom headers
+ if (this.headers != null) {
+ foreach (string key in this.headers.Keys) {
+ if (this.headers[key] == null)
+ continue;
+
+ switch (key.ToLower())
+ {
+ // in silverlight 3, these are set by the web browser that hosts the Silverlight application.
+ // http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest%28v=vs.95%29.aspx
+ case "connection":
+ case "content-length":
+ case "expect":
+ case "if-modified-since":
+ case "referer":
+ case "transfer-encoding":
+ case "user-agent":
+ break;
+
+ // in silverlight this isn't supported, can not find reference to why not
+ case "range":
+ break;
+
+ // in .NET Framework 3.5 and below, these are set by the system.
+ // http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest%28v=VS.90%29.aspx
+ case "date":
+ case "host":
+ break;
+
+ case "accept":
+ this.req.Accept = (string)this.headers[key];
+ break;
+
+ case "content-type":
+ this.req.ContentType = (string)this.headers[key];
+ break;
+ default:
+ this.req.Headers[key] = (string)this.headers[key];
+ break;
+ }
+ }
+ }
+
+ IAsyncResult asyncResult = this.req.BeginGetRequestStream(new AsyncCallback(RequestStreamCallback), this.req);
+
+ return true;
+ }
+
+ /// <summary>
+ /// Cancels uploading the current file.
+ /// </summary>
+ public void CancelUpload() {
+ if (this.req != null) {
+ this.req.Abort();
+ this.req = null;
+ DisposeStreams();
+ }
+ }
+
+ #region protected methods
+
+ protected virtual void OnUploadComplete(UploadEventArgs e) {
+ DisposeStreams();
+
+ if (UploadComplete != null)
+ UploadComplete(this, e);
+ }
+
+ protected virtual void OnUploadChunkComplete(UploadEventArgs e) {
+ if (UploadChunkComplete != null)
+ UploadChunkComplete(this, e);
+ }
+
+ protected virtual void OnIOError(ErrorEventArgs e) {
+ DisposeStreams();
+
+ if (Error != null)
+ Error(this, e);
+ }
+
+ protected virtual void OnProgress(ProgressEventArgs e) {
+ if (Progress != null)
+ Progress(this, e);
+ }
+
+ #endregion
+
+ #region private methods
+
+ private void RequestStreamCallback(IAsyncResult ar) {
+ HttpWebRequest request = (HttpWebRequest) ar.AsyncState;
+ string boundary = "----pluploadboundary" + DateTime.Now.Ticks, dashdash = "--", crlf = "\r\n";
+ Stream requestStream = null;
+ byte[] buffer = new byte[1048576], strBuff;
+ int bytes;
+ long loaded = 0, end = 0;
+ int percent, lastPercent = 0;
+
+ try {
+ requestStream = request.EndGetRequestStream(ar);
+
+ if (this.multipart) {
+ request.ContentType = "multipart/form-data; boundary=" + boundary;
+
+ // Add name to multipart array
+ this.multipartParams["name"] = this.targetName;
+
+ // Add chunking when needed
+ if (this.chunking) {
+ this.multipartParams["chunk"] = this.chunk;
+ this.multipartParams["chunks"] = this.chunks;
+ }
+
+ // Append mutlipart parameters
+ foreach (KeyValuePair<string, object> pair in this.multipartParams) {
+ strBuff = this.StrToByteArray(dashdash + boundary + crlf +
+ "Content-Disposition: form-data; name=\"" + pair.Key + '"' + crlf + crlf +
+ pair.Value + crlf
+ );
+
+ requestStream.Write(strBuff, 0, strBuff.Length);
+ }
+
+ // Append multipart file header
+ strBuff = this.StrToByteArray(
+ dashdash + boundary + crlf +
+ "Content-Disposition: form-data; name=\"" + this.fileDataName + "\"; filename=\"" + this.name + '"' +
+ crlf + "Content-Type: " + this.mimeType + crlf + crlf
+ );
+
+ requestStream.Write(strBuff, 0, strBuff.Length);
+ } else {
+ request.ContentType = "application/octet-stream";
+ }
+
+ // Move to start
+ loaded = this.chunk * this.chunkSize;
+
+ // Find end
+ end = (this.chunk + 1) * this.chunkSize;
+ if (end > this.Size)
+ end = this.Size;
+
+ while (loaded < end && (bytes = ReadByteRange(buffer, loaded, 0, (int)(end - loaded < buffer.Length ? end - loaded : buffer.Length))) != 0) {
+ loaded += bytes;
+ percent = (int) Math.Round((double) loaded / (double) this.Size * 100.0);
+
+ if (percent > lastPercent) {
+ syncContext.Post(delegate {
+ if (percent > lastPercent) {
+ this.OnProgress(new ProgressEventArgs(loaded, this.Size));
+ lastPercent = percent;
+ }
+ }, this);
+ }
+
+ requestStream.Write(buffer, 0, bytes);
+ requestStream.Flush();
+ }
+
+ // Append multipart file footer
+ if (this.multipart) {
+ strBuff = this.StrToByteArray(crlf + dashdash + boundary + dashdash + crlf);
+ requestStream.Write(strBuff, 0, strBuff.Length);
+ }
+ } catch (Exception ex) {
+ syncContext.Send(delegate {
+ this.OnIOError(new ErrorEventArgs(ex.Message, this.chunk, this.chunks));
+ }, this);
+ } finally {
+ try {
+ if (requestStream != null) {
+ requestStream.Close();
+ requestStream.Dispose();
+ requestStream = null;
+ }
+ } catch (Exception ex) {
+ syncContext.Send(delegate {
+ this.OnIOError(new ErrorEventArgs(ex.Message, this.chunk, this.chunks));
+ }, this);
+ }
+ }
+
+ try {
+ request.BeginGetResponse(new AsyncCallback(ResponseCallback), request);
+ }
+ catch (WebException ex)
+ {
+ if (ex.Status != WebExceptionStatus.RequestCanceled) {
+ syncContext.Send(delegate {
+ this.OnIOError(new ErrorEventArgs(ex.Message, this.chunk, this.chunks));
+ }, this);
+ }
+ }
+ catch (Exception ex) {
+ syncContext.Send(delegate {
+ this.OnIOError(new ErrorEventArgs(ex.Message, this.chunk, this.chunks));
+ }, this);
+ }
+ }
+
+ private void ResponseCallback(IAsyncResult ar) {
+ try
+ {
+ HttpWebRequest request = ar.AsyncState as HttpWebRequest;
+
+ WebResponse response = request.EndGetResponse(ar);
+
+ syncContext.Post(ExtractResponse, response);
+ }
+ catch (WebException ex) {
+ if (ex.Status != WebExceptionStatus.RequestCanceled) {
+ syncContext.Send(delegate {
+ this.OnIOError(new ErrorEventArgs(ex.Message, this.chunk, this.chunks));
+ }, this);
+ }
+ }
+ catch (Exception ex) {
+ syncContext.Send(delegate {
+ this.OnIOError(new ErrorEventArgs(ex.Message, this.chunk, this.chunks));
+ }, this);
+ }
+ }
+
+ private void ExtractResponse(object state) {
+ HttpWebResponse response = state as HttpWebResponse;
+ StreamReader respReader = null;
+ Stream respStream = null;
+ string content;
+
+ try {
+ respStream = response.GetResponseStream();
+
+ if (response.StatusCode == HttpStatusCode.OK) {
+ respReader = new StreamReader(respStream);
+
+ if (respStream != null) {
+ content = respReader.ReadToEnd();
+ } else
+ throw new Exception("Error could not open response stream.");
+ } else
+ throw new Exception("Error server returned status: " + ((int) response.StatusCode) + " " + response.StatusDescription);
+
+ this.chunk++;
+
+ syncContext.Send(delegate {
+ this.OnUploadChunkComplete(new UploadEventArgs(content, this.chunk - 1, this.chunks));
+ }, this);
+ } catch (Exception ex) {
+ syncContext.Send(delegate {
+ this.OnIOError(new ErrorEventArgs(ex.Message, chunk, chunks));
+ }, this);
+ } finally {
+ if (respStream != null)
+ respStream.Close();
+
+ if (respReader != null)
+ respReader.Close();
+
+ response.Close();
+ }
+ }
+
+ private void DisposeStreams() {
+ if (fileStream != null) {
+ fileStream.Dispose();
+ fileStream = null;
+ }
+
+ if (imageStream != null) {
+ imageStream.Dispose();
+ imageStream = null;
+ }
+ }
+
+ private void Debug(string msg) {
+ ((ScriptObject) HtmlPage.Window.Eval("console")).Invoke("log", new string[] {msg});
+ }
+
+ private Stream ResizeImage(Stream image_stream, int width, int height, int quality, ImageType type) {
+ try {
+ // Load the image as a writeablebitmap
+ WriteableBitmap writableBitmap;
+ BitmapImage bitmapImage = new BitmapImage();
+ bitmapImage.SetSource(image_stream);
+ writableBitmap = new WriteableBitmap(bitmapImage);
+
+ if (width == 0) {
+ width = writableBitmap.PixelWidth;
+ }
+
+ if (height == 0) {
+ height = writableBitmap.PixelHeight;
+ }
+
+ double scale = Math.Min((double) width / writableBitmap.PixelWidth, (double) height / writableBitmap.PixelHeight);
+
+ // No resize needed
+ if (scale >= 1.0 && (quality == 0 || type != ImageType.Jpeg))
+ return image_stream;
+
+ if (quality == 0) {
+ quality = 90;
+ }
+
+ // Setup shorter names and pixelbuffers
+ int w = writableBitmap.PixelWidth;
+ int h = writableBitmap.PixelHeight;
+ int[] p = writableBitmap.Pixels;
+ byte[][,] imageRaster = new byte[3][,]; // RGB colors
+ imageRaster[0] = new byte[w, h];
+ imageRaster[1] = new byte[w, h];
+ imageRaster[2] = new byte[w, h];
+
+ // Copy WriteableBitmap data into buffer for FluxJpeg
+ int i = 0;
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < w; x++) {
+ int color = p[i++];
+
+ imageRaster[0][x, y] = (byte) (color >> 16); // R
+ imageRaster[1][x, y] = (byte) (color >> 8); // G
+ imageRaster[2][x, y] = (byte) (color); // B
+ }
+ }
+
+ // Create new FluxJpeg image based on pixel data
+ Image jpegImage = new Image(new ColorModel {
+ colorspace = ColorSpace.RGB
+ }, imageRaster);
+
+ ImageResizer resizer = new ImageResizer(jpegImage);
+ Image resizedImage;
+
+ if (scale < 1.0) {
+ // Calc new proportional size
+ width = (int) Math.Round(writableBitmap.PixelWidth * scale);
+ height = (int) Math.Round(writableBitmap.PixelHeight * scale);
+
+ // Resize the image
+ resizedImage = resizer.Resize(width, height, FluxJpeg.Core.Filtering.ResamplingFilters.LowpassAntiAlias);
+ } else {
+ resizedImage = jpegImage;
+ }
+
+ Stream imageStream = new MemoryStream();
+
+ if (type == ImageType.Jpeg) {
+ // Encode the resized image as Jpeg
+ JpegEncoder jpegEncoder = new JpegEncoder(resizedImage, quality, imageStream);
+ jpegEncoder.Encode();
+ } else {
+ int[] pixelBuffer = new int[resizedImage.Height * resizedImage.Width];
+ byte[][,] resizedRaster = resizedImage.Raster;
+
+ // Convert FJCore raster to PixelBuffer
+ for (int y = 0; y < resizedImage.Height; y++) {
+ for (int x = 0; x < resizedImage.Width; x++) {
+ int color = 0;
+
+ color = color | resizedRaster[0][x, y] << 16; // R
+ color = color | resizedRaster[1][x, y] << 8; // G
+ color = color | resizedRaster[2][x, y]; // B
+
+ pixelBuffer[(y * resizedImage.Width) + x] = color;
+ }
+ }
+
+ // Encode the resized image as Png
+ PngEncoder pngEncoder = new PngEncoder(pixelBuffer, resizedImage.Width, resizedImage.Height, false, PngEncoder.FILTER_NONE, Deflater.BEST_COMPRESSION);
+ byte[] pngBuffer = pngEncoder.pngEncode();
+ imageStream.Write(pngBuffer, 0, pngBuffer.Length);
+ }
+
+ return imageStream;
+ } catch {
+ // Ignore the error and let the server resize the image
+ }
+
+ return image_stream;
+ }
+
+ private byte[] StrToByteArray(string str) {
+ System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
+
+ return encoding.GetBytes(str);
+ }
+
+ #endregion
+ }
+
+ /// <summary>
+ /// Upload event arguments class.
+ /// </summary>
+ public class UploadEventArgs : EventArgs {
+ #region private fields
+ private string response;
+ private long chunk;
+ private int chunks;
+ #endregion
+
+ /// <summary>
+ /// Main constructor for the upload event.
+ /// </summary>
+ /// <param name="response">Response contents as a string.</param>
+ public UploadEventArgs(string response) : this(response, 0, 0) {
+ }
+
+ /// <summary>
+ /// Main constructor for the upload event.
+ /// </summary>
+ /// <param name="response">Response contents as a string.</param>
+ /// <param name="chunk">Current chunk number.</param>
+ /// <param name="chunks">Total chunks.</param>
+ public UploadEventArgs(string response, long chunk, int chunks) {
+ this.response = response;
+ this.chunk = chunk;
+ this.chunks = chunks;
+ }
+
+ /// <summary>Response from upload request.</summary>
+ public string Response {
+ get { return response; }
+ }
+
+ /// <summary>Chunk number.</summary>
+ public long Chunk {
+ get { return chunk; }
+ }
+
+ /// <summary>Total number of chunks.</summary>
+ public int Chunks {
+ get { return chunks; }
+ }
+ }
+
+ /// <summary>
+ /// Error event arguments class.
+ /// </summary>
+ public class ErrorEventArgs : EventArgs {
+ #region private fields
+ private string message;
+ private long chunk;
+ private int chunks;
+ #endregion
+
+ /// <summary>
+ /// Main constructor for the error event.
+ /// </summary>
+ /// <param name="message">Error message.</param>
+ public ErrorEventArgs(string message) : this(message, 0, 0) {
+ this.message = message;
+ }
+
+ /// <summary>
+ /// Main constructor for the error event.
+ /// </summary>
+ /// <param name="message">Error message.</param>
+ /// <param name="chunk">Current chunk number.</param>
+ /// <param name="chunks">Total chunks.</param>
+ public ErrorEventArgs(string message, long chunk, int chunks) {
+ this.message = message;
+ this.chunk = chunk;
+ this.chunks = chunks;
+ }
+
+ /// <summary>Chunk number.</summary>
+ public long Chunk {
+ get { return chunk; }
+ }
+
+ /// <summary>Total number of chunks.</summary>
+ public int Chunks {
+ get { return chunks; }
+ }
+
+ /// <summary>Error message.</summary>
+ public string Message {
+ get { return message; }
+ }
+ }
+
+ /// <summary>
+ /// Progress event arguments class.
+ /// </summary>
+ public class ProgressEventArgs : EventArgs {
+ #region private fields
+ private long loaded, total;
+ #endregion
+
+ /// <summary>
+ /// Main constructor for the progress events args.
+ /// </summary>
+ /// <param name="loaded">Number of bytes uploaded.</param>
+ /// <param name="total">Total bytes to upload.</param>
+ public ProgressEventArgs(long loaded, long total) {
+ this.loaded = loaded;
+ this.total = total;
+ }
+
+ /// <summary>Total bytes to upload.</summary>
+ public long Total {
+ get { return total; }
+ }
+
+ /// <summary>Number of bytes upload so far.</summary>
+ public long Loaded {
+ get { return loaded; }
+ }
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/Page.xaml b/debian/missing-sources/plupload/csharp/Plupload/Page.xaml
new file mode 100644
index 0000000..6236e84
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/Page.xaml
@@ -0,0 +1,7 @@
+<UserControl
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ x:Class="Moxiecode.Plupload.Page"
+ Width="1024" Height="1024" Background="Transparent" Cursor="Hand">
+ <Canvas Background="Transparent"></Canvas>
+</UserControl> \ No newline at end of file
diff --git a/debian/missing-sources/plupload/csharp/Plupload/Page.xaml.cs b/debian/missing-sources/plupload/csharp/Plupload/Page.xaml.cs
new file mode 100644
index 0000000..66bfeef
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/Page.xaml.cs
@@ -0,0 +1,230 @@
+/**
+ * Page.xaml.cs
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using System.Windows.Browser;
+using System.Net;
+using System.IO;
+using System.Collections.Generic;
+using System.Threading;
+using Moxiecode.Plupload;
+
+namespace Moxiecode.Plupload {
+ /// <summary>
+ /// Partial page class for the Silverlight page.
+ /// </summary>
+ public partial class Page : UserControl {
+ #region private fields
+ private Dictionary<string, FileReference> files;
+ private int idCount = 0;
+ private FileReference currentFile;
+ private string id, filter;
+ private bool multiselect;
+ private bool disabled = false;
+ #endregion
+
+ /// <summary>
+ /// Main constructor.
+ /// </summary>
+ /// <param name="init_params">Silverlight init params.</param>
+ public Page(IDictionary<string, string> init_params) {
+ InitializeComponent();
+
+ HtmlPage.RegisterScriptableObject("Upload", this);
+
+ this.files = new Dictionary<string, FileReference>();
+ this.id = init_params["id"];
+ this.filter = init_params["filter"];
+ this.multiselect = Convert.ToBoolean(init_params["multiselect"]);
+
+ this.FireEvent("Init");
+ this.MouseLeftButtonUp += new MouseButtonEventHandler(OnClick);
+
+ this.MouseLeftButtonDown += new MouseButtonEventHandler(OnMouseLeftButtonDown);
+ this.MouseEnter += new MouseEventHandler(OnMouseEnter);
+ this.MouseLeave += new MouseEventHandler(OnMouseLeave);
+ }
+
+ private void OnClick(object sender, MouseEventArgs e) {
+ if (this.disabled) {
+ return;
+ }
+
+ OpenFileDialog dlg = new OpenFileDialog();
+
+ this.FireEvent("StartSelectFiles");
+
+ try {
+ dlg.Multiselect = this.multiselect;
+ dlg.Filter = this.filter;
+
+ if ((bool) dlg.ShowDialog()) {
+ foreach (FileInfo file in dlg.Files) {
+ FileReference uploadFile = new FileReference("u" + this.idCount++, file);
+
+ uploadFile.UploadChunkComplete += delegate(object up_sender, UploadEventArgs args) {
+ FileReference evtFile = (FileReference) up_sender;
+
+ this.FireEvent("UploadChunkSuccessful", evtFile.Id, args.Chunk, args.Chunks, args.Response);
+ };
+
+ uploadFile.UploadComplete += delegate(object up_sender, UploadEventArgs args) {
+ FileReference evtFile = (FileReference) up_sender;
+
+ this.FireEvent("UploadSuccessful", evtFile.Id, args.Response);
+ };
+
+ uploadFile.Error += delegate(object up_sender, ErrorEventArgs args) {
+ FileReference evtFile = (FileReference) up_sender;
+
+ this.FireEvent("UploadChunkError", evtFile.Id, args.Chunk, args.Chunks, args.Message);
+ };
+
+ uploadFile.Progress += delegate(object up_sender, ProgressEventArgs args) {
+ FileReference evtFile = (FileReference) up_sender;
+
+ this.FireEvent("UploadFileProgress", evtFile.Id, args.Loaded, args.Total);
+ };
+
+ this.FireEvent("SelectFile", uploadFile.Id, uploadFile.Name, uploadFile.Size);
+ this.files[uploadFile.Id] = uploadFile;
+ }
+
+ this.FireEvent("SelectSuccessful");
+ } else
+ this.FireEvent("SelectCancelled");
+ } catch (Exception ex) {
+ this.FireEvent("SelectError", ex.Message);
+ }
+ }
+
+
+ private void OnMouseLeftButtonDown(object sender, MouseEventArgs e) {
+ this.FireEvent("MouseLeftButtonDown");
+ }
+
+ private void OnMouseEnter(object sender, MouseEventArgs e) {
+ this.FireEvent("MouseEnter");
+ }
+
+ private void OnMouseLeave(object sender, MouseEventArgs e) {
+ this.FireEvent("MouseLeave");
+ }
+
+ /// <summary>
+ /// Reference to page level plupload.silverlight script object.
+ /// </summary>
+ public ScriptObject PluploadScriptObject {
+ get { return ((ScriptObject) HtmlPage.Window.Eval("plupload.silverlight")); }
+ }
+
+ /// <summary>
+ /// Fires a specific event to the page level multi upload script.
+ /// </summary>
+ /// <param name="name">Event name to fire.</param>
+ public void FireEvent(string name) {
+ this.PluploadScriptObject.Invoke("trigger", new string[] { this.id, name });
+ }
+
+ /// <summary>
+ /// Fires a specific event to the page level multi upload script.
+ /// </summary>
+ /// <param name="name">Event name to fire.</param>
+ /// <param name="paramlist">Numerous parameters to send.</param>
+ public void FireEvent(string name, params object[] paramlist) {
+ List<object> args = new List<object>(paramlist);
+
+ args.Insert(0, name);
+ args.Insert(0, this.id);
+
+ this.PluploadScriptObject.Invoke("trigger", args.ToArray());
+ }
+
+ [ScriptableMember]
+ /// <summary>
+ /// Uploads a specific file by id to the specific url and using a chunks.
+ /// </summary>
+ /// <param name="id">File id to upload.</param>
+ /// <param name="upload_url">Url to upload to.</param>
+ /// <param name="chunk_size">Chunk size to use.</param>
+ public void UploadFile(string id, string upload_url, string json_settings) {
+ if (this.files.ContainsKey(id)) {
+ FileReference file = this.files[id];
+
+ this.currentFile = file;
+ file.Upload(upload_url, json_settings);
+ }
+ }
+
+ [ScriptableMember]
+ /// <summary>
+ /// Removes the specified file by id.
+ /// </summary>
+ /// <param name="id">File id to remove.</param>
+ public void RemoveFile(string id) {
+ if (this.files.ContainsKey(id))
+ this.files[id] = null;
+ }
+
+ [ScriptableMember]
+ /// <summary>
+ /// Clears all files.
+ /// </summary>
+ public void ClearFiles() {
+ this.files = new Dictionary<string, FileReference>();
+ }
+
+ [ScriptableMember]
+ /// <summary>
+ /// Uploads the next chunk of the current file. Returns true/false if there is more chunks.
+ /// </summary>
+ /// <return>true/false if there is more chunks</return>
+ public bool UploadNextChunk() {
+ if (this.currentFile != null)
+ return this.currentFile.UploadNextChunk();
+
+ return false;
+ }
+
+ [ScriptableMember]
+ /// <summary>
+ /// Cancel upload.
+ /// </summary>
+ public void CancelUpload() {
+ if (this.currentFile != null)
+ this.currentFile.CancelUpload();
+ }
+
+ [ScriptableMember]
+ /// <summary>
+ /// Disable dialog trigger.
+ /// </summary>
+ public void DisableBrowse(bool disabled = true)
+ {
+ this.disabled = disabled;
+ }
+
+ /// <summary>
+ /// Send debug message to firebug console.
+ /// </summary>
+ /// <param name="msg">Message to write.</param>
+ private void Debug(string msg) {
+ ((ScriptObject) HtmlPage.Window.Eval("console")).Invoke("log", new string[] { msg });
+ }
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/Plupload.csproj b/debian/missing-sources/plupload/csharp/Plupload/Plupload.csproj
new file mode 100644
index 0000000..b40f00f
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/Plupload.csproj
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'">
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ </PropertyGroup>
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <DefaultClrNameSpace>Plupload</DefaultClrNameSpace>
+ <AssemblyName>plupload.silverlight</AssemblyName>
+ <RootNamespace>Moxiecode.Plupload</RootNamespace>
+ <AlwaysCompileMarkupFilesInSeparateDomain>false</AlwaysCompileMarkupFilesInSeparateDomain>
+ <ExpressionBlendCreationVersion>2.1.1535.0</ExpressionBlendCreationVersion>
+ <ProjectGuid>{95F0DEE8-DE7A-46C5-9DCC-0570B0FC4643}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <NoStdLib>true</NoStdLib>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <StartPageUrl>Default.html</StartPageUrl>
+ <XapOutputs>true</XapOutputs>
+ <XapFilename>plupload.silverlight.xap</XapFilename>
+ <GenerateSilverlightManifest>true</GenerateSilverlightManifest>
+ <SilverlightManifestTemplate>Properties\AppManifest.xml</SilverlightManifestTemplate>
+ <SilverlightAppEntry>Moxiecode.Plupload.App</SilverlightAppEntry>
+ <CreateTestPage>true</CreateTestPage>
+ <TestPageFileName>Default.html</TestPageFileName>
+ <DefineConstants>SILVERLIGHT</DefineConstants>
+ <SilverlightApplication>true</SilverlightApplication>
+ <SourceAnalysisOverrideSettingsFile>C:\Users\spocke\AppData\Roaming\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
+ <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+ <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
+ <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ <UsePlatformExtensions>true</UsePlatformExtensions>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;SILVERLIGHT</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>PdbOnly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>SILVERLIGHT</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <DebugSymbols>false</DebugSymbols>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+ <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
+ <RegisterForComInterop>False</RegisterForComInterop>
+ <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
+ <BaseAddress>4194304</BaseAddress>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <FileAlignment>4096</FileAlignment>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="mscorlib" />
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Net" />
+ <Reference Include="System.Windows" />
+ <Reference Include="System.Windows.Browser" />
+ <Reference Include="System.Xml" />
+ <ApplicationDefinition Include="App.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </ApplicationDefinition>
+ <Compile Include="App.xaml.cs">
+ <DependentUpon>App.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="FJCore\DCT.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\DecodedJpeg.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\Decoder\HuffmanTable.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\Decoder\JpegHuffmanTable.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\Decoder\JpegQuantizationTable.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\Encoder\JpegEncoder.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\FDCT.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\Filter\Convolution.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\Filter\FilterBase.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\Filter\FilterLowpassResize.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\Filter\FilterNNResize.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\Filter\GrayImage.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\Image.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\IO\BinaryWriter.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\JpegMarker.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\Resize\ImageResizer.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\YCbCr.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="FJCore\ZigZag.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Page.xaml.cs">
+ <DependentUpon>Page.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="PngEncoder\Adler32.cs" />
+ <Compile Include="PngEncoder\CRC32.cs" />
+ <Compile Include="PngEncoder\Deflater.cs" />
+ <Compile Include="PngEncoder\DeflaterConstants.cs" />
+ <Compile Include="PngEncoder\DeflaterEngine.cs" />
+ <Compile Include="PngEncoder\DeflaterHuffman.cs" />
+ <Compile Include="PngEncoder\DeflaterOutputStream.cs" />
+ <Compile Include="PngEncoder\DeflaterPending.cs" />
+ <Compile Include="PngEncoder\IChecksum.cs" />
+ <Compile Include="PngEncoder\PngEncoder.cs" />
+ <Compile Include="PngEncoder\PendingBuffer.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Page Include="Page.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <None Include="Properties\AppManifest.xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="FileReference.cs" />
+ <Compile Include="Utils\JsonReader.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.VisualBasic.PowerPacks.10.0">
+ <Visible>False</Visible>
+ <ProductName>Microsoft Visual Basic PowerPacks 10.0</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 3.1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <ItemGroup />
+ <ItemGroup>
+ <Content Include="FJCore\IJG.txt" />
+ <Content Include="FJCore\JAI.txt" />
+ <Content Include="FJCore\License.txt" />
+ <Content Include="FJCore\README.txt" />
+ </ItemGroup>
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
+ <PropertyGroup>
+ <PostBuildEvent>copy /Y plupload.silverlight.xap ..\..\..\..\js\plupload.silverlight.xap</PostBuildEvent>
+ </PropertyGroup>
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
+ <SilverlightProjectProperties />
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+</Project>
diff --git a/debian/missing-sources/plupload/csharp/Plupload/Plupload.sln b/debian/missing-sources/plupload/csharp/Plupload/Plupload.sln
new file mode 100644
index 0000000..47a792e
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/Plupload.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plupload", "Plupload.csproj", "{95F0DEE8-DE7A-46C5-9DCC-0570B0FC4643}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {95F0DEE8-DE7A-46C5-9DCC-0570B0FC4643}.Debug|Any CPU.ActiveCfg = Release|Any CPU
+ {95F0DEE8-DE7A-46C5-9DCC-0570B0FC4643}.Debug|Any CPU.Build.0 = Release|Any CPU
+ {95F0DEE8-DE7A-46C5-9DCC-0570B0FC4643}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {95F0DEE8-DE7A-46C5-9DCC-0570B0FC4643}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/Adler32.cs b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/Adler32.cs
new file mode 100644
index 0000000..febc82e
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/Adler32.cs
@@ -0,0 +1,216 @@
+// Adler32.cs - Computes Adler32 data checksum of a data stream
+// Copyright (C) 2001 Mike Krueger
+//
+// This file was translated from java, it was part of the GNU Classpath
+// Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+using System;
+
+namespace Plupload.PngEncoder {
+
+ /// <summary>
+ /// Computes Adler32 checksum for a stream of data. An Adler32
+ /// checksum is not as reliable as a CRC32 checksum, but a lot faster to
+ /// compute.
+ ///
+ /// The specification for Adler32 may be found in RFC 1950.
+ /// ZLIB Compressed Data Format Specification version 3.3)
+ ///
+ ///
+ /// From that document:
+ ///
+ /// "ADLER32 (Adler-32 checksum)
+ /// This contains a checksum value of the uncompressed data
+ /// (excluding any dictionary data) computed according to Adler-32
+ /// algorithm. This algorithm is a 32-bit extension and improvement
+ /// of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
+ /// standard.
+ ///
+ /// Adler-32 is composed of two sums accumulated per byte: s1 is
+ /// the sum of all bytes, s2 is the sum of all s1 values. Both sums
+ /// are done modulo 65521. s1 is initialized to 1, s2 to zero. The
+ /// Adler-32 checksum is stored as s2*65536 + s1 in most-
+ /// significant-byte first (network) order."
+ ///
+ /// "8.2. The Adler-32 algorithm
+ ///
+ /// The Adler-32 algorithm is much faster than the CRC32 algorithm yet
+ /// still provides an extremely low probability of undetected errors.
+ ///
+ /// The modulo on unsigned long accumulators can be delayed for 5552
+ /// bytes, so the modulo operation time is negligible. If the bytes
+ /// are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
+ /// and order sensitive, unlike the first sum, which is just a
+ /// checksum. That 65521 is prime is important to avoid a possible
+ /// large class of two-byte errors that leave the check unchanged.
+ /// (The Fletcher checksum uses 255, which is not prime and which also
+ /// makes the Fletcher check insensitive to single byte changes 0 -
+ /// 255.)
+ ///
+ /// The sum s1 is initialized to 1 instead of zero to make the length
+ /// of the sequence part of s2, so that the length does not have to be
+ /// checked separately. (Any sequence of zeroes has a Fletcher
+ /// checksum of zero.)"
+ /// </summary>
+ /// <see cref="ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream"/>
+ /// <see cref="ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream"/>
+ public sealed class Adler32 : IChecksum {
+ /// <summary>
+ /// largest prime smaller than 65536
+ /// </summary>
+ const uint BASE = 65521;
+
+ /// <summary>
+ /// Returns the Adler32 data checksum computed so far.
+ /// </summary>
+ public long Value {
+ get {
+ return checksum;
+ }
+ }
+
+ /// <summary>
+ /// Creates a new instance of the Adler32 class.
+ /// The checksum starts off with a value of 1.
+ /// </summary>
+ public Adler32() {
+ Reset();
+ }
+
+ /// <summary>
+ /// Resets the Adler32 checksum to the initial value.
+ /// </summary>
+ public void Reset() {
+ checksum = 1;
+ }
+
+ /// <summary>
+ /// Updates the checksum with a byte value.
+ /// </summary>
+ /// <param name="value">
+ /// The data value to add. The high byte of the int is ignored.
+ /// </param>
+ public void Update(int value) {
+ // We could make a length 1 byte array and call update again, but I
+ // would rather not have that overhead
+ uint s1 = checksum & 0xFFFF;
+ uint s2 = checksum >> 16;
+
+ s1 = (s1 + ((uint) value & 0xFF)) % BASE;
+ s2 = (s1 + s2) % BASE;
+
+ checksum = (s2 << 16) + s1;
+ }
+
+ /// <summary>
+ /// Updates the checksum with an array of bytes.
+ /// </summary>
+ /// <param name="buffer">
+ /// The source of the data to update with.
+ /// </param>
+ public void Update(byte[] buffer) {
+ if (buffer == null) {
+ throw new ArgumentNullException("buffer");
+ }
+
+ Update(buffer, 0, buffer.Length);
+ }
+
+ /// <summary>
+ /// Updates the checksum with the bytes taken from the array.
+ /// </summary>
+ /// <param name="buffer">
+ /// an array of bytes
+ /// </param>
+ /// <param name="offset">
+ /// the start of the data used for this update
+ /// </param>
+ /// <param name="count">
+ /// the number of bytes to use for this update
+ /// </param>
+ public void Update(byte[] buffer, int offset, int count) {
+ if (buffer == null) {
+ throw new ArgumentNullException("buffer");
+ }
+
+ if (offset < 0) {
+
+ throw new ArgumentOutOfRangeException("offset");
+
+ }
+
+ if (count < 0) {
+
+ throw new ArgumentOutOfRangeException("count");
+
+ }
+
+ if (offset >= buffer.Length) {
+ throw new ArgumentOutOfRangeException("offset");
+
+ }
+
+ if (offset + count > buffer.Length) {
+ throw new ArgumentOutOfRangeException("count");
+ }
+
+ //(By Per Bothner)
+ uint s1 = checksum & 0xFFFF;
+ uint s2 = checksum >> 16;
+
+ while (count > 0) {
+ // We can defer the modulo operation:
+ // s1 maximally grows from 65521 to 65521 + 255 * 3800
+ // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
+ int n = 3800;
+ if (n > count) {
+ n = count;
+ }
+ count -= n;
+ while (--n >= 0) {
+ s1 = s1 + (uint) (buffer[offset++] & 0xff);
+ s2 = s2 + s1;
+ }
+ s1 %= BASE;
+ s2 %= BASE;
+ }
+
+ checksum = (s2 << 16) | s1;
+ }
+
+ #region Instance Fields
+ uint checksum;
+ #endregion
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/CRC32.cs b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/CRC32.cs
new file mode 100644
index 0000000..685fc57
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/CRC32.cs
@@ -0,0 +1,213 @@
+// CRC32.cs - Computes CRC32 data checksum of a data stream
+// Copyright (C) 2001 Mike Krueger
+//
+// This file was translated from java, it was part of the GNU Classpath
+// Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+using System;
+
+namespace Plupload.PngEncoder {
+
+ /// <summary>
+ /// Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
+ /// x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+ ///
+ /// Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ /// with the lowest powers in the most significant bit. Then adding polynomials
+ /// is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ /// one. If we call the above polynomial p, and represent a byte as the
+ /// polynomial q, also with the lowest power in the most significant bit (so the
+ /// byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ /// where a mod b means the remainder after dividing a by b.
+ ///
+ /// This calculation is done using the shift-register method of multiplying and
+ /// taking the remainder. The register is initialized to zero, and for each
+ /// incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ /// x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ /// x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ /// out is a one). We start with the highest power (least significant bit) of
+ /// q and repeat for all eight bits of q.
+ ///
+ /// The table is simply the CRC of all possible eight bit values. This is all
+ /// the information needed to generate CRC's on data a byte at a time for all
+ /// combinations of CRC register values and incoming bytes.
+ /// </summary>
+ public sealed class Crc32 : IChecksum {
+ const uint CrcSeed = 0xFFFFFFFF;
+
+ readonly static uint[] CrcTable = new uint[] {
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419,
+ 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4,
+ 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07,
+ 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856,
+ 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
+ 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
+ 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3,
+ 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A,
+ 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599,
+ 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190,
+ 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
+ 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E,
+ 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED,
+ 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
+ 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3,
+ 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
+ 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
+ 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010,
+ 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17,
+ 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6,
+ 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615,
+ 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344,
+ 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
+ 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A,
+ 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1,
+ 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C,
+ 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
+ 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE,
+ 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
+ 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C,
+ 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B,
+ 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
+ 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1,
+ 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278,
+ 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
+ 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66,
+ 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
+ 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8,
+ 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B,
+ 0x2D02EF8D
+ };
+
+ internal static uint ComputeCrc32(uint oldCrc, byte value) {
+ return (uint) (Crc32.CrcTable[(oldCrc ^ value) & 0xFF] ^ (oldCrc >> 8));
+ }
+
+ /// <summary>
+ /// The crc data checksum so far.
+ /// </summary>
+ uint crc;
+
+ /// <summary>
+ /// Returns the CRC32 data checksum computed so far.
+ /// </summary>
+ public long Value {
+ get {
+ return (long) crc;
+ }
+ set {
+ crc = (uint) value;
+ }
+ }
+
+ /// <summary>
+ /// Resets the CRC32 data checksum as if no update was ever called.
+ /// </summary>
+ public void Reset() {
+ crc = 0;
+ }
+
+ /// <summary>
+ /// Updates the checksum with the int bval.
+ /// </summary>
+ /// <param name = "value">
+ /// the byte is taken as the lower 8 bits of value
+ /// </param>
+ public void Update(int value) {
+ crc ^= CrcSeed;
+ crc = CrcTable[(crc ^ value) & 0xFF] ^ (crc >> 8);
+ crc ^= CrcSeed;
+ }
+
+ /// <summary>
+ /// Updates the checksum with the bytes taken from the array.
+ /// </summary>
+ /// <param name="buffer">
+ /// buffer an array of bytes
+ /// </param>
+ public void Update(byte[] buffer) {
+ if (buffer == null) {
+ throw new ArgumentNullException("buffer");
+ }
+
+ Update(buffer, 0, buffer.Length);
+ }
+
+ /// <summary>
+ /// Adds the byte array to the data checksum.
+ /// </summary>
+ /// <param name = "buffer">
+ /// The buffer which contains the data
+ /// </param>
+ /// <param name = "offset">
+ /// The offset in the buffer where the data starts
+ /// </param>
+ /// <param name = "count">
+ /// The number of data bytes to update the CRC with.
+ /// </param>
+ public void Update(byte[] buffer, int offset, int count) {
+ if (buffer == null) {
+ throw new ArgumentNullException("buffer");
+ }
+
+ if (count < 0) {
+
+ throw new ArgumentOutOfRangeException("count");
+ }
+
+ if (offset < 0 || offset + count > buffer.Length) {
+ throw new ArgumentOutOfRangeException("offset");
+ }
+
+ crc ^= CrcSeed;
+
+ while (--count >= 0) {
+ crc = CrcTable[(crc ^ buffer[offset++]) & 0xFF] ^ (crc >> 8);
+ }
+
+ crc ^= CrcSeed;
+ }
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/Deflater.cs b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/Deflater.cs
new file mode 100644
index 0000000..f4a2094
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/Deflater.cs
@@ -0,0 +1,543 @@
+// Deflater.cs
+//
+// Copyright (C) 2001 Mike Krueger
+// Copyright (C) 2004 John Reilly
+//
+// This file was translated from java, it was part of the GNU Classpath
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+using System;
+
+namespace Plupload.PngEncoder {
+
+ /// <summary>
+ /// This is the Deflater class. The deflater class compresses input
+ /// with the deflate algorithm described in RFC 1951. It has several
+ /// compression levels and three different strategies described below.
+ ///
+ /// This class is <i>not</i> thread safe. This is inherent in the API, due
+ /// to the split of deflate and setInput.
+ ///
+ /// author of the original java version : Jochen Hoenicke
+ /// </summary>
+ public class Deflater {
+ #region Deflater Documentation
+ /*
+ * The Deflater can do the following state transitions:
+ *
+ * (1) -> INIT_STATE ----> INIT_FINISHING_STATE ---.
+ * / | (2) (5) |
+ * / v (5) |
+ * (3)| SETDICT_STATE ---> SETDICT_FINISHING_STATE |(3)
+ * \ | (3) | ,--------'
+ * | | | (3) /
+ * v v (5) v v
+ * (1) -> BUSY_STATE ----> FINISHING_STATE
+ * | (6)
+ * v
+ * FINISHED_STATE
+ * \_____________________________________/
+ * | (7)
+ * v
+ * CLOSED_STATE
+ *
+ * (1) If we should produce a header we start in INIT_STATE, otherwise
+ * we start in BUSY_STATE.
+ * (2) A dictionary may be set only when we are in INIT_STATE, then
+ * we change the state as indicated.
+ * (3) Whether a dictionary is set or not, on the first call of deflate
+ * we change to BUSY_STATE.
+ * (4) -- intentionally left blank -- :)
+ * (5) FINISHING_STATE is entered, when flush() is called to indicate that
+ * there is no more INPUT. There are also states indicating, that
+ * the header wasn't written yet.
+ * (6) FINISHED_STATE is entered, when everything has been flushed to the
+ * internal pending output buffer.
+ * (7) At any time (7)
+ *
+ */
+ #endregion
+ #region Public Constants
+ /// <summary>
+ /// The best and slowest compression level. This tries to find very
+ /// long and distant string repetitions.
+ /// </summary>
+ public const int BEST_COMPRESSION = 9;
+
+ /// <summary>
+ /// The worst but fastest compression level.
+ /// </summary>
+ public const int BEST_SPEED = 1;
+
+ /// <summary>
+ /// The default compression level.
+ /// </summary>
+ public const int DEFAULT_COMPRESSION = -1;
+
+ /// <summary>
+ /// This level won't compress at all but output uncompressed blocks.
+ /// </summary>
+ public const int NO_COMPRESSION = 0;
+
+ /// <summary>
+ /// The compression method. This is the only method supported so far.
+ /// There is no need to use this constant at all.
+ /// </summary>
+ public const int DEFLATED = 8;
+ #endregion
+ #region Local Constants
+ private const int IS_SETDICT = 0x01;
+ private const int IS_FLUSHING = 0x04;
+ private const int IS_FINISHING = 0x08;
+
+ private const int INIT_STATE = 0x00;
+ private const int SETDICT_STATE = 0x01;
+ // private static int INIT_FINISHING_STATE = 0x08;
+ // private static int SETDICT_FINISHING_STATE = 0x09;
+ private const int BUSY_STATE = 0x10;
+ private const int FLUSHING_STATE = 0x14;
+ private const int FINISHING_STATE = 0x1c;
+ private const int FINISHED_STATE = 0x1e;
+ private const int CLOSED_STATE = 0x7f;
+ #endregion
+ #region Constructors
+ /// <summary>
+ /// Creates a new deflater with default compression level.
+ /// </summary>
+ public Deflater()
+ : this(DEFAULT_COMPRESSION, false) {
+
+ }
+
+ /// <summary>
+ /// Creates a new deflater with given compression level.
+ /// </summary>
+ /// <param name="level">
+ /// the compression level, a value between NO_COMPRESSION
+ /// and BEST_COMPRESSION, or DEFAULT_COMPRESSION.
+ /// </param>
+ /// <exception cref="System.ArgumentOutOfRangeException">if lvl is out of range.</exception>
+ public Deflater(int level)
+ : this(level, false) {
+
+ }
+
+ /// <summary>
+ /// Creates a new deflater with given compression level.
+ /// </summary>
+ /// <param name="level">
+ /// the compression level, a value between NO_COMPRESSION
+ /// and BEST_COMPRESSION.
+ /// </param>
+ /// <param name="noZlibHeaderOrFooter">
+ /// true, if we should suppress the Zlib/RFC1950 header at the
+ /// beginning and the adler checksum at the end of the output. This is
+ /// useful for the GZIP/PKZIP formats.
+ /// </param>
+ /// <exception cref="System.ArgumentOutOfRangeException">if lvl is out of range.</exception>
+ public Deflater(int level, bool noZlibHeaderOrFooter) {
+ if (level == DEFAULT_COMPRESSION) {
+ level = 6;
+ } else if (level < NO_COMPRESSION || level > BEST_COMPRESSION) {
+ throw new ArgumentOutOfRangeException("level");
+ }
+
+ pending = new DeflaterPending();
+ engine = new DeflaterEngine(pending);
+ this.noZlibHeaderOrFooter = noZlibHeaderOrFooter;
+ SetStrategy(DeflateStrategy.Default);
+ SetLevel(level);
+ Reset();
+ }
+ #endregion
+
+ /// <summary>
+ /// Resets the deflater. The deflater acts afterwards as if it was
+ /// just created with the same compression level and strategy as it
+ /// had before.
+ /// </summary>
+ public void Reset() {
+ state = (noZlibHeaderOrFooter ? BUSY_STATE : INIT_STATE);
+ totalOut = 0;
+ pending.Reset();
+ engine.Reset();
+ }
+
+ /// <summary>
+ /// Gets the current adler checksum of the data that was processed so far.
+ /// </summary>
+ public int Adler {
+ get {
+ return engine.Adler;
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of input bytes processed so far.
+ /// </summary>
+ public long TotalIn {
+ get {
+ return engine.TotalIn;
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of output bytes so far.
+ /// </summary>
+ public long TotalOut {
+ get {
+ return totalOut;
+ }
+ }
+
+ /// <summary>
+ /// Flushes the current input block. Further calls to deflate() will
+ /// produce enough output to inflate everything in the current input
+ /// block. This is not part of Sun's JDK so I have made it package
+ /// private. It is used by DeflaterOutputStream to implement
+ /// flush().
+ /// </summary>
+ public void Flush() {
+ state |= IS_FLUSHING;
+ }
+
+ /// <summary>
+ /// Finishes the deflater with the current input block. It is an error
+ /// to give more input after this method was called. This method must
+ /// be called to force all bytes to be flushed.
+ /// </summary>
+ public void Finish() {
+ state |= (IS_FLUSHING | IS_FINISHING);
+ }
+
+ /// <summary>
+ /// Returns true if the stream was finished and no more output bytes
+ /// are available.
+ /// </summary>
+ public bool IsFinished {
+ get {
+ return (state == FINISHED_STATE) && pending.IsFlushed;
+ }
+ }
+
+ /// <summary>
+ /// Returns true, if the input buffer is empty.
+ /// You should then call setInput().
+ /// NOTE: This method can also return true when the stream
+ /// was finished.
+ /// </summary>
+ public bool IsNeedingInput {
+ get {
+ return engine.NeedsInput();
+ }
+ }
+
+ /// <summary>
+ /// Sets the data which should be compressed next. This should be only
+ /// called when needsInput indicates that more input is needed.
+ /// If you call setInput when needsInput() returns false, the
+ /// previous input that is still pending will be thrown away.
+ /// The given byte array should not be changed, before needsInput() returns
+ /// true again.
+ /// This call is equivalent to <code>setInput(input, 0, input.length)</code>.
+ /// </summary>
+ /// <param name="input">
+ /// the buffer containing the input data.
+ /// </param>
+ /// <exception cref="System.InvalidOperationException">
+ /// if the buffer was finished() or ended().
+ /// </exception>
+ public void SetInput(byte[] input) {
+ SetInput(input, 0, input.Length);
+ }
+
+ /// <summary>
+ /// Sets the data which should be compressed next. This should be
+ /// only called when needsInput indicates that more input is needed.
+ /// The given byte array should not be changed, before needsInput() returns
+ /// true again.
+ /// </summary>
+ /// <param name="input">
+ /// the buffer containing the input data.
+ /// </param>
+ /// <param name="offset">
+ /// the start of the data.
+ /// </param>
+ /// <param name="count">
+ /// the number of data bytes of input.
+ /// </param>
+ /// <exception cref="System.InvalidOperationException">
+ /// if the buffer was Finish()ed or if previous input is still pending.
+ /// </exception>
+ public void SetInput(byte[] input, int offset, int count) {
+ if ((state & IS_FINISHING) != 0) {
+ throw new InvalidOperationException("Finish() already called");
+ }
+ engine.SetInput(input, offset, count);
+ }
+
+ /// <summary>
+ /// Sets the compression level. There is no guarantee of the exact
+ /// position of the change, but if you call this when needsInput is
+ /// true the change of compression level will occur somewhere near
+ /// before the end of the so far given input.
+ /// </summary>
+ /// <param name="level">
+ /// the new compression level.
+ /// </param>
+ public void SetLevel(int level) {
+ if (level == DEFAULT_COMPRESSION) {
+ level = 6;
+ } else if (level < NO_COMPRESSION || level > BEST_COMPRESSION) {
+ throw new ArgumentOutOfRangeException("level");
+ }
+
+ if (this.level != level) {
+ this.level = level;
+ engine.SetLevel(level);
+ }
+ }
+
+ /// <summary>
+ /// Get current compression level
+ /// </summary>
+ /// <returns>Returns the current compression level</returns>
+ public int GetLevel() {
+ return level;
+ }
+
+ /// <summary>
+ /// Sets the compression strategy. Strategy is one of
+ /// DEFAULT_STRATEGY, HUFFMAN_ONLY and FILTERED. For the exact
+ /// position where the strategy is changed, the same as for
+ /// SetLevel() applies.
+ /// </summary>
+ /// <param name="strategy">
+ /// The new compression strategy.
+ /// </param>
+ public void SetStrategy(DeflateStrategy strategy) {
+ engine.Strategy = strategy;
+ }
+
+ /// <summary>
+ /// Deflates the current input block with to the given array.
+ /// </summary>
+ /// <param name="output">
+ /// The buffer where compressed data is stored
+ /// </param>
+ /// <returns>
+ /// The number of compressed bytes added to the output, or 0 if either
+ /// IsNeedingInput() or IsFinished returns true or length is zero.
+ /// </returns>
+ public int Deflate(byte[] output) {
+ return Deflate(output, 0, output.Length);
+ }
+
+ /// <summary>
+ /// Deflates the current input block to the given array.
+ /// </summary>
+ /// <param name="output">
+ /// Buffer to store the compressed data.
+ /// </param>
+ /// <param name="offset">
+ /// Offset into the output array.
+ /// </param>
+ /// <param name="length">
+ /// The maximum number of bytes that may be stored.
+ /// </param>
+ /// <returns>
+ /// The number of compressed bytes added to the output, or 0 if either
+ /// needsInput() or finished() returns true or length is zero.
+ /// </returns>
+ /// <exception cref="System.InvalidOperationException">
+ /// If Finish() was previously called.
+ /// </exception>
+ /// <exception cref="System.ArgumentOutOfRangeException">
+ /// If offset or length don't match the array length.
+ /// </exception>
+ public int Deflate(byte[] output, int offset, int length) {
+ int origLength = length;
+
+ if (state == CLOSED_STATE) {
+ throw new InvalidOperationException("Deflater closed");
+ }
+
+ if (state < BUSY_STATE) {
+ // output header
+ int header = (DEFLATED +
+ ((DeflaterConstants.MAX_WBITS - 8) << 4)) << 8;
+ int level_flags = (level - 1) >> 1;
+ if (level_flags < 0 || level_flags > 3) {
+ level_flags = 3;
+ }
+ header |= level_flags << 6;
+ if ((state & IS_SETDICT) != 0) {
+ // Dictionary was set
+ header |= DeflaterConstants.PRESET_DICT;
+ }
+ header += 31 - (header % 31);
+
+ pending.WriteShortMSB(header);
+ if ((state & IS_SETDICT) != 0) {
+ int chksum = engine.Adler;
+ engine.ResetAdler();
+ pending.WriteShortMSB(chksum >> 16);
+ pending.WriteShortMSB(chksum & 0xffff);
+ }
+
+ state = BUSY_STATE | (state & (IS_FLUSHING | IS_FINISHING));
+ }
+
+ for (; ; ) {
+ int count = pending.Flush(output, offset, length);
+ offset += count;
+ totalOut += count;
+ length -= count;
+
+ if (length == 0 || state == FINISHED_STATE) {
+ break;
+ }
+
+ if (!engine.Deflate((state & IS_FLUSHING) != 0, (state & IS_FINISHING) != 0)) {
+ if (state == BUSY_STATE) {
+ // We need more input now
+ return origLength - length;
+ } else if (state == FLUSHING_STATE) {
+ if (level != NO_COMPRESSION) {
+ /* We have to supply some lookahead. 8 bit lookahead
+ * is needed by the zlib inflater, and we must fill
+ * the next byte, so that all bits are flushed.
+ */
+ int neededbits = 8 + ((-pending.BitCount) & 7);
+ while (neededbits > 0) {
+ /* write a static tree block consisting solely of
+ * an EOF:
+ */
+ pending.WriteBits(2, 10);
+ neededbits -= 10;
+ }
+ }
+ state = BUSY_STATE;
+ } else if (state == FINISHING_STATE) {
+ pending.AlignToByte();
+
+ // Compressed data is complete. Write footer information if required.
+ if (!noZlibHeaderOrFooter) {
+ int adler = engine.Adler;
+ pending.WriteShortMSB(adler >> 16);
+ pending.WriteShortMSB(adler & 0xffff);
+ }
+ state = FINISHED_STATE;
+ }
+ }
+ }
+ return origLength - length;
+ }
+
+ /// <summary>
+ /// Sets the dictionary which should be used in the deflate process.
+ /// This call is equivalent to <code>setDictionary(dict, 0, dict.Length)</code>.
+ /// </summary>
+ /// <param name="dictionary">
+ /// the dictionary.
+ /// </param>
+ /// <exception cref="System.InvalidOperationException">
+ /// if SetInput () or Deflate () were already called or another dictionary was already set.
+ /// </exception>
+ public void SetDictionary(byte[] dictionary) {
+ SetDictionary(dictionary, 0, dictionary.Length);
+ }
+
+ /// <summary>
+ /// Sets the dictionary which should be used in the deflate process.
+ /// The dictionary is a byte array containing strings that are
+ /// likely to occur in the data which should be compressed. The
+ /// dictionary is not stored in the compressed output, only a
+ /// checksum. To decompress the output you need to supply the same
+ /// dictionary again.
+ /// </summary>
+ /// <param name="dictionary">
+ /// The dictionary data
+ /// </param>
+ /// <param name="index">
+ /// The index where dictionary information commences.
+ /// </param>
+ /// <param name="count">
+ /// The number of bytes in the dictionary.
+ /// </param>
+ /// <exception cref="System.InvalidOperationException">
+ /// If SetInput () or Deflate() were already called or another dictionary was already set.
+ /// </exception>
+ public void SetDictionary(byte[] dictionary, int index, int count) {
+ if (state != INIT_STATE) {
+ throw new InvalidOperationException();
+ }
+
+ state = SETDICT_STATE;
+ engine.SetDictionary(dictionary, index, count);
+ }
+
+ #region Instance Fields
+ /// <summary>
+ /// Compression level.
+ /// </summary>
+ int level;
+
+ /// <summary>
+ /// If true no Zlib/RFC1950 headers or footers are generated
+ /// </summary>
+ bool noZlibHeaderOrFooter;
+
+ /// <summary>
+ /// The current state.
+ /// </summary>
+ int state;
+
+ /// <summary>
+ /// The total bytes of output written.
+ /// </summary>
+ long totalOut;
+
+ /// <summary>
+ /// The pending output.
+ /// </summary>
+ DeflaterPending pending;
+
+ /// <summary>
+ /// The deflater engine.
+ /// </summary>
+ DeflaterEngine engine;
+ #endregion
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterConstants.cs b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterConstants.cs
new file mode 100644
index 0000000..46587b6
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterConstants.cs
@@ -0,0 +1,184 @@
+// DeflaterConstants.cs
+//
+// Copyright (C) 2001 Mike Krueger
+// Copyright (C) 2004 John Reilly
+//
+// This file was translated from java, it was part of the GNU Classpath
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+using System;
+
+namespace Plupload.PngEncoder {
+
+ /// <summary>
+ /// This class contains constants used for deflation.
+ /// </summary>
+ public class DeflaterConstants {
+ /// <summary>
+ /// Set to true to enable debugging
+ /// </summary>
+ public const bool DEBUGGING = false;
+
+ /// <summary>
+ /// Written to Zip file to identify a stored block
+ /// </summary>
+ public const int STORED_BLOCK = 0;
+
+ /// <summary>
+ /// Identifies static tree in Zip file
+ /// </summary>
+ public const int STATIC_TREES = 1;
+
+ /// <summary>
+ /// Identifies dynamic tree in Zip file
+ /// </summary>
+ public const int DYN_TREES = 2;
+
+ /// <summary>
+ /// Header flag indicating a preset dictionary for deflation
+ /// </summary>
+ public const int PRESET_DICT = 0x20;
+
+ /// <summary>
+ /// Sets internal buffer sizes for Huffman encoding
+ /// </summary>
+ public const int DEFAULT_MEM_LEVEL = 8;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int MAX_MATCH = 258;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int MIN_MATCH = 3;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int MAX_WBITS = 15;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int WSIZE = 1 << MAX_WBITS;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int WMASK = WSIZE - 1;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int HASH_BITS = DEFAULT_MEM_LEVEL + 7;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int HASH_SIZE = 1 << HASH_BITS;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int HASH_MASK = HASH_SIZE - 1;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int HASH_SHIFT = (HASH_BITS + MIN_MATCH - 1) / MIN_MATCH;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int MAX_DIST = WSIZE - MIN_LOOKAHEAD;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int PENDING_BUF_SIZE = 1 << (DEFAULT_MEM_LEVEL + 8);
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public static int MAX_BLOCK_SIZE = Math.Min(65535, PENDING_BUF_SIZE - 5);
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int DEFLATE_STORED = 0;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int DEFLATE_FAST = 1;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public const int DEFLATE_SLOW = 2;
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public static int[] GOOD_LENGTH = { 0, 4, 4, 4, 4, 8, 8, 8, 32, 32 };
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public static int[] MAX_LAZY = { 0, 4, 5, 6, 4, 16, 16, 32, 128, 258 };
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public static int[] NICE_LENGTH = { 0, 8, 16, 32, 16, 32, 128, 128, 258, 258 };
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public static int[] MAX_CHAIN = { 0, 4, 8, 32, 16, 32, 128, 256, 1024, 4096 };
+
+ /// <summary>
+ /// Internal compression engine constant
+ /// </summary>
+ public static int[] COMPR_FUNC = { 0, 1, 1, 1, 1, 2, 2, 2, 2, 2 };
+
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterEngine.cs b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterEngine.cs
new file mode 100644
index 0000000..7b56b59
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterEngine.cs
@@ -0,0 +1,832 @@
+// DeflaterEngine.cs
+//
+// Copyright (C) 2001 Mike Krueger
+// Copyright (C) 2004 John Reilly
+//
+// This file was translated from java, it was part of the GNU Classpath
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+using System;
+
+namespace Plupload.PngEncoder {
+
+ /// <summary>
+ /// Strategies for deflater
+ /// </summary>
+ public enum DeflateStrategy {
+ /// <summary>
+ /// The default strategy
+ /// </summary>
+ Default = 0,
+
+ /// <summary>
+ /// This strategy will only allow longer string repetitions. It is
+ /// useful for random data with a small character set.
+ /// </summary>
+ Filtered = 1,
+
+
+ /// <summary>
+ /// This strategy will not look for string repetitions at all. It
+ /// only encodes with Huffman trees (which means, that more common
+ /// characters get a smaller encoding.
+ /// </summary>
+ HuffmanOnly = 2
+ }
+
+ // DEFLATE ALGORITHM:
+ //
+ // The uncompressed stream is inserted into the window array. When
+ // the window array is full the first half is thrown away and the
+ // second half is copied to the beginning.
+ //
+ // The head array is a hash table. Three characters build a hash value
+ // and they the value points to the corresponding index in window of
+ // the last string with this hash. The prev array implements a
+ // linked list of matches with the same hash: prev[index & WMASK] points
+ // to the previous index with the same hash.
+ //
+
+
+ /// <summary>
+ /// Low level compression engine for deflate algorithm which uses a 32K sliding window
+ /// with secondary compression from Huffman/Shannon-Fano codes.
+ /// </summary>
+ public class DeflaterEngine : DeflaterConstants {
+ #region Constants
+ const int TooFar = 4096;
+ #endregion
+
+ #region Constructors
+ /// <summary>
+ /// Construct instance with pending buffer
+ /// </summary>
+ /// <param name="pending">
+ /// Pending buffer to use
+ /// </param>>
+ public DeflaterEngine(DeflaterPending pending) {
+ this.pending = pending;
+ huffman = new DeflaterHuffman(pending);
+ adler = new Adler32();
+
+ window = new byte[2 * WSIZE];
+ head = new short[HASH_SIZE];
+ prev = new short[WSIZE];
+
+ // We start at index 1, to avoid an implementation deficiency, that
+ // we cannot build a repeat pattern at index 0.
+ blockStart = strstart = 1;
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Deflate drives actual compression of data
+ /// </summary>
+ /// <param name="flush">True to flush input buffers</param>
+ /// <param name="finish">Finish deflation with the current input.</param>
+ /// <returns>Returns true if progress has been made.</returns>
+ public bool Deflate(bool flush, bool finish) {
+ bool progress;
+ do {
+ FillWindow();
+ bool canFlush = flush && (inputOff == inputEnd);
+
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING) {
+ Console.WriteLine("window: [" + blockStart + "," + strstart + ","
+ + lookahead + "], " + compressionFunction + "," + canFlush);
+ }
+#endif
+ switch (compressionFunction) {
+ case DEFLATE_STORED:
+ progress = DeflateStored(canFlush, finish);
+ break;
+ case DEFLATE_FAST:
+ progress = DeflateFast(canFlush, finish);
+ break;
+ case DEFLATE_SLOW:
+ progress = DeflateSlow(canFlush, finish);
+ break;
+ default:
+ throw new InvalidOperationException("unknown compressionFunction");
+ }
+ } while (pending.IsFlushed && progress); // repeat while we have no pending output and progress was made
+ return progress;
+ }
+
+ /// <summary>
+ /// Sets input data to be deflated. Should only be called when <code>NeedsInput()</code>
+ /// returns true
+ /// </summary>
+ /// <param name="buffer">The buffer containing input data.</param>
+ /// <param name="offset">The offset of the first byte of data.</param>
+ /// <param name="count">The number of bytes of data to use as input.</param>
+ public void SetInput(byte[] buffer, int offset, int count) {
+ if (buffer == null) {
+ throw new ArgumentNullException("buffer");
+ }
+
+ if (offset < 0) {
+ throw new ArgumentOutOfRangeException("offset");
+ }
+
+ if (count < 0) {
+ throw new ArgumentOutOfRangeException("count");
+ }
+
+ if (inputOff < inputEnd) {
+ throw new InvalidOperationException("Old input was not completely processed");
+ }
+
+ int end = offset + count;
+
+ /* We want to throw an ArrayIndexOutOfBoundsException early. The
+ * check is very tricky: it also handles integer wrap around.
+ */
+ if ((offset > end) || (end > buffer.Length)) {
+ throw new ArgumentOutOfRangeException("count");
+ }
+
+ inputBuf = buffer;
+ inputOff = offset;
+ inputEnd = end;
+ }
+
+ /// <summary>
+ /// Determines if more <see cref="SetInput">input</see> is needed.
+ /// </summary>
+ /// <returns>Return true if input is needed via <see cref="SetInput">SetInput</see></returns>
+ public bool NeedsInput() {
+ return (inputEnd == inputOff);
+ }
+
+ /// <summary>
+ /// Set compression dictionary
+ /// </summary>
+ /// <param name="buffer">The buffer containing the dictionary data</param>
+ /// <param name="offset">The offset in the buffer for the first byte of data</param>
+ /// <param name="length">The length of the dictionary data.</param>
+ public void SetDictionary(byte[] buffer, int offset, int length) {
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING && (strstart != 1) )
+ {
+ throw new InvalidOperationException("strstart not 1");
+ }
+#endif
+ adler.Update(buffer, offset, length);
+ if (length < MIN_MATCH) {
+ return;
+ }
+
+ if (length > MAX_DIST) {
+ offset += length - MAX_DIST;
+ length = MAX_DIST;
+ }
+
+ System.Array.Copy(buffer, offset, window, strstart, length);
+
+ UpdateHash();
+ --length;
+ while (--length > 0) {
+ InsertString();
+ strstart++;
+ }
+ strstart += 2;
+ blockStart = strstart;
+ }
+
+ /// <summary>
+ /// Reset internal state
+ /// </summary>
+ public void Reset() {
+ huffman.Reset();
+ adler.Reset();
+ blockStart = strstart = 1;
+ lookahead = 0;
+ totalIn = 0;
+ prevAvailable = false;
+ matchLen = MIN_MATCH - 1;
+
+ for (int i = 0; i < HASH_SIZE; i++) {
+ head[i] = 0;
+ }
+
+ for (int i = 0; i < WSIZE; i++) {
+ prev[i] = 0;
+ }
+ }
+
+ /// <summary>
+ /// Reset Adler checksum
+ /// </summary>
+ public void ResetAdler() {
+ adler.Reset();
+ }
+
+ /// <summary>
+ /// Get current value of Adler checksum
+ /// </summary>
+ public int Adler {
+ get {
+ return unchecked((int) adler.Value);
+ }
+ }
+
+ /// <summary>
+ /// Total data processed
+ /// </summary>
+ public long TotalIn {
+ get {
+ return totalIn;
+ }
+ }
+
+ /// <summary>
+ /// Get/set the <see cref="DeflateStrategy">deflate strategy</see>
+ /// </summary>
+ public DeflateStrategy Strategy {
+ get {
+ return strategy;
+ }
+ set {
+ strategy = value;
+ }
+ }
+
+ /// <summary>
+ /// Set the deflate level (0-9)
+ /// </summary>
+ /// <param name="level">The value to set the level to.</param>
+ public void SetLevel(int level) {
+ if ((level < 0) || (level > 9)) {
+ throw new ArgumentOutOfRangeException("level");
+ }
+
+ goodLength = DeflaterConstants.GOOD_LENGTH[level];
+ max_lazy = DeflaterConstants.MAX_LAZY[level];
+ niceLength = DeflaterConstants.NICE_LENGTH[level];
+ max_chain = DeflaterConstants.MAX_CHAIN[level];
+
+ if (DeflaterConstants.COMPR_FUNC[level] != compressionFunction) {
+
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING) {
+ Console.WriteLine("Change from " + compressionFunction + " to "
+ + DeflaterConstants.COMPR_FUNC[level]);
+ }
+#endif
+ switch (compressionFunction) {
+ case DEFLATE_STORED:
+ if (strstart > blockStart) {
+ huffman.FlushStoredBlock(window, blockStart,
+ strstart - blockStart, false);
+ blockStart = strstart;
+ }
+ UpdateHash();
+ break;
+
+ case DEFLATE_FAST:
+ if (strstart > blockStart) {
+ huffman.FlushBlock(window, blockStart, strstart - blockStart,
+ false);
+ blockStart = strstart;
+ }
+ break;
+
+ case DEFLATE_SLOW:
+ if (prevAvailable) {
+ huffman.TallyLit(window[strstart - 1] & 0xff);
+ }
+ if (strstart > blockStart) {
+ huffman.FlushBlock(window, blockStart, strstart - blockStart, false);
+ blockStart = strstart;
+ }
+ prevAvailable = false;
+ matchLen = MIN_MATCH - 1;
+ break;
+ }
+ compressionFunction = COMPR_FUNC[level];
+ }
+ }
+
+ /// <summary>
+ /// Fill the window
+ /// </summary>
+ public void FillWindow() {
+ /* If the window is almost full and there is insufficient lookahead,
+ * move the upper half to the lower one to make room in the upper half.
+ */
+ if (strstart >= WSIZE + MAX_DIST) {
+ SlideWindow();
+ }
+
+ /* If there is not enough lookahead, but still some input left,
+ * read in the input
+ */
+ while (lookahead < DeflaterConstants.MIN_LOOKAHEAD && inputOff < inputEnd) {
+ int more = 2 * WSIZE - lookahead - strstart;
+
+ if (more > inputEnd - inputOff) {
+ more = inputEnd - inputOff;
+ }
+
+ System.Array.Copy(inputBuf, inputOff, window, strstart + lookahead, more);
+ adler.Update(inputBuf, inputOff, more);
+
+ inputOff += more;
+ totalIn += more;
+ lookahead += more;
+ }
+
+ if (lookahead >= MIN_MATCH) {
+ UpdateHash();
+ }
+ }
+
+ void UpdateHash() {
+ /*
+ if (DEBUGGING) {
+ Console.WriteLine("updateHash: "+strstart);
+ }
+ */
+ ins_h = (window[strstart] << HASH_SHIFT) ^ window[strstart + 1];
+ }
+
+ /// <summary>
+ /// Inserts the current string in the head hash and returns the previous
+ /// value for this hash.
+ /// </summary>
+ /// <returns>The previous hash value</returns>
+ int InsertString() {
+ short match;
+ int hash = ((ins_h << HASH_SHIFT) ^ window[strstart + (MIN_MATCH - 1)]) & HASH_MASK;
+
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING)
+ {
+ if (hash != (((window[strstart] << (2*HASH_SHIFT)) ^
+ (window[strstart + 1] << HASH_SHIFT) ^
+ (window[strstart + 2])) & HASH_MASK)) {
+ throw new SharpZipBaseException("hash inconsistent: " + hash + "/"
+ +window[strstart] + ","
+ +window[strstart + 1] + ","
+ +window[strstart + 2] + "," + HASH_SHIFT);
+ }
+ }
+#endif
+ prev[strstart & WMASK] = match = head[hash];
+ head[hash] = unchecked((short) strstart);
+ ins_h = hash;
+ return match & 0xffff;
+ }
+
+ void SlideWindow() {
+ Array.Copy(window, WSIZE, window, 0, WSIZE);
+ matchStart -= WSIZE;
+ strstart -= WSIZE;
+ blockStart -= WSIZE;
+
+ // Slide the hash table (could be avoided with 32 bit values
+ // at the expense of memory usage).
+ for (int i = 0; i < HASH_SIZE; ++i) {
+ int m = head[i] & 0xffff;
+ head[i] = (short) (m >= WSIZE ? (m - WSIZE) : 0);
+ }
+
+ // Slide the prev table.
+ for (int i = 0; i < WSIZE; i++) {
+ int m = prev[i] & 0xffff;
+ prev[i] = (short) (m >= WSIZE ? (m - WSIZE) : 0);
+ }
+ }
+
+ /// <summary>
+ /// Find the best (longest) string in the window matching the
+ /// string starting at strstart.
+ ///
+ /// Preconditions:
+ /// <code>
+ /// strstart + MAX_MATCH &lt;= window.length.</code>
+ /// </summary>
+ /// <param name="curMatch"></param>
+ /// <returns>True if a match greater than the minimum length is found</returns>
+ bool FindLongestMatch(int curMatch) {
+ int chainLength = this.max_chain;
+ int niceLength = this.niceLength;
+ short[] prev = this.prev;
+ int scan = this.strstart;
+ int match;
+ int best_end = this.strstart + matchLen;
+ int best_len = Math.Max(matchLen, MIN_MATCH - 1);
+
+ int limit = Math.Max(strstart - MAX_DIST, 0);
+
+ int strend = strstart + MAX_MATCH - 1;
+ byte scan_end1 = window[best_end - 1];
+ byte scan_end = window[best_end];
+
+ // Do not waste too much time if we already have a good match:
+ if (best_len >= this.goodLength) {
+ chainLength >>= 2;
+ }
+
+ /* Do not look for matches beyond the end of the input. This is necessary
+ * to make deflate deterministic.
+ */
+ if (niceLength > lookahead) {
+ niceLength = lookahead;
+ }
+
+#if DebugDeflation
+
+ if (DeflaterConstants.DEBUGGING && (strstart > 2 * WSIZE - MIN_LOOKAHEAD))
+ {
+ throw new InvalidOperationException("need lookahead");
+ }
+#endif
+
+ do {
+
+#if DebugDeflation
+
+ if (DeflaterConstants.DEBUGGING && (curMatch >= strstart) )
+ {
+ throw new InvalidOperationException("no future");
+ }
+#endif
+ if (window[curMatch + best_len] != scan_end ||
+ window[curMatch + best_len - 1] != scan_end1 ||
+ window[curMatch] != window[scan] ||
+ window[curMatch + 1] != window[scan + 1]) {
+ continue;
+ }
+
+ match = curMatch + 2;
+ scan += 2;
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart + 258.
+ */
+ while (
+ window[++scan] == window[++match] &&
+ window[++scan] == window[++match] &&
+ window[++scan] == window[++match] &&
+ window[++scan] == window[++match] &&
+ window[++scan] == window[++match] &&
+ window[++scan] == window[++match] &&
+ window[++scan] == window[++match] &&
+ window[++scan] == window[++match] &&
+ (scan < strend)) {
+ // Do nothing
+ }
+
+ if (scan > best_end) {
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING && (ins_h == 0) )
+ Console.Error.WriteLine("Found match: " + curMatch + "-" + (scan - strstart));
+#endif
+ matchStart = curMatch;
+ best_end = scan;
+ best_len = scan - strstart;
+
+ if (best_len >= niceLength) {
+ break;
+ }
+
+ scan_end1 = window[best_end - 1];
+ scan_end = window[best_end];
+ }
+ scan = strstart;
+ } while ((curMatch = (prev[curMatch & WMASK] & 0xffff)) > limit && --chainLength != 0);
+
+ matchLen = Math.Min(best_len, lookahead);
+ return matchLen >= MIN_MATCH;
+ }
+
+ bool DeflateStored(bool flush, bool finish) {
+ if (!flush && (lookahead == 0)) {
+ return false;
+ }
+
+ strstart += lookahead;
+ lookahead = 0;
+
+ int storedLength = strstart - blockStart;
+
+ if ((storedLength >= DeflaterConstants.MAX_BLOCK_SIZE) || // Block is full
+ (blockStart < WSIZE && storedLength >= MAX_DIST) || // Block may move out of window
+ flush) {
+ bool lastBlock = finish;
+ if (storedLength > DeflaterConstants.MAX_BLOCK_SIZE) {
+ storedLength = DeflaterConstants.MAX_BLOCK_SIZE;
+ lastBlock = false;
+ }
+
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING)
+ {
+ Console.WriteLine("storedBlock[" + storedLength + "," + lastBlock + "]");
+ }
+#endif
+
+ huffman.FlushStoredBlock(window, blockStart, storedLength, lastBlock);
+ blockStart += storedLength;
+ return !lastBlock;
+ }
+ return true;
+ }
+
+ bool DeflateFast(bool flush, bool finish) {
+ if (lookahead < MIN_LOOKAHEAD && !flush) {
+ return false;
+ }
+
+ while (lookahead >= MIN_LOOKAHEAD || flush) {
+ if (lookahead == 0) {
+ // We are flushing everything
+ huffman.FlushBlock(window, blockStart, strstart - blockStart, finish);
+ blockStart = strstart;
+ return false;
+ }
+
+ if (strstart > 2 * WSIZE - MIN_LOOKAHEAD) {
+ /* slide window, as FindLongestMatch needs this.
+ * This should only happen when flushing and the window
+ * is almost full.
+ */
+ SlideWindow();
+ }
+
+ int hashHead;
+ if (lookahead >= MIN_MATCH &&
+ (hashHead = InsertString()) != 0 &&
+ strategy != DeflateStrategy.HuffmanOnly &&
+ strstart - hashHead <= MAX_DIST &&
+ FindLongestMatch(hashHead)) {
+ // longestMatch sets matchStart and matchLen
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING)
+ {
+ for (int i = 0 ; i < matchLen; i++) {
+ if (window[strstart + i] != window[matchStart + i]) {
+ throw new SharpZipBaseException("Match failure");
+ }
+ }
+ }
+#endif
+
+ bool full = huffman.TallyDist(strstart - matchStart, matchLen);
+
+ lookahead -= matchLen;
+ if (matchLen <= max_lazy && lookahead >= MIN_MATCH) {
+ while (--matchLen > 0) {
+ ++strstart;
+ InsertString();
+ }
+ ++strstart;
+ } else {
+ strstart += matchLen;
+ if (lookahead >= MIN_MATCH - 1) {
+ UpdateHash();
+ }
+ }
+ matchLen = MIN_MATCH - 1;
+ if (!full) {
+ continue;
+ }
+ } else {
+ // No match found
+ huffman.TallyLit(window[strstart] & 0xff);
+ ++strstart;
+ --lookahead;
+ }
+
+ if (huffman.IsFull()) {
+ bool lastBlock = finish && (lookahead == 0);
+ huffman.FlushBlock(window, blockStart, strstart - blockStart, lastBlock);
+ blockStart = strstart;
+ return !lastBlock;
+ }
+ }
+ return true;
+ }
+
+ bool DeflateSlow(bool flush, bool finish) {
+ if (lookahead < MIN_LOOKAHEAD && !flush) {
+ return false;
+ }
+
+ while (lookahead >= MIN_LOOKAHEAD || flush) {
+ if (lookahead == 0) {
+ if (prevAvailable) {
+ huffman.TallyLit(window[strstart - 1] & 0xff);
+ }
+ prevAvailable = false;
+
+ // We are flushing everything
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING && !flush)
+ {
+ throw new SharpZipBaseException("Not flushing, but no lookahead");
+ }
+#endif
+ huffman.FlushBlock(window, blockStart, strstart - blockStart,
+ finish);
+ blockStart = strstart;
+ return false;
+ }
+
+ if (strstart >= 2 * WSIZE - MIN_LOOKAHEAD) {
+ /* slide window, as FindLongestMatch needs this.
+ * This should only happen when flushing and the window
+ * is almost full.
+ */
+ SlideWindow();
+ }
+
+ int prevMatch = matchStart;
+ int prevLen = matchLen;
+ if (lookahead >= MIN_MATCH) {
+
+ int hashHead = InsertString();
+
+ if (strategy != DeflateStrategy.HuffmanOnly &&
+ hashHead != 0 &&
+ strstart - hashHead <= MAX_DIST &&
+ FindLongestMatch(hashHead)) {
+
+ // longestMatch sets matchStart and matchLen
+
+ // Discard match if too small and too far away
+ if (matchLen <= 5 && (strategy == DeflateStrategy.Filtered || (matchLen == MIN_MATCH && strstart - matchStart > TooFar))) {
+ matchLen = MIN_MATCH - 1;
+ }
+ }
+ }
+
+ // previous match was better
+ if ((prevLen >= MIN_MATCH) && (matchLen <= prevLen)) {
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING)
+ {
+ for (int i = 0 ; i < matchLen; i++) {
+ if (window[strstart-1+i] != window[prevMatch + i])
+ throw new SharpZipBaseException();
+ }
+ }
+#endif
+ huffman.TallyDist(strstart - 1 - prevMatch, prevLen);
+ prevLen -= 2;
+ do {
+ strstart++;
+ lookahead--;
+ if (lookahead >= MIN_MATCH) {
+ InsertString();
+ }
+ } while (--prevLen > 0);
+
+ strstart++;
+ lookahead--;
+ prevAvailable = false;
+ matchLen = MIN_MATCH - 1;
+ } else {
+ if (prevAvailable) {
+ huffman.TallyLit(window[strstart - 1] & 0xff);
+ }
+ prevAvailable = true;
+ strstart++;
+ lookahead--;
+ }
+
+ if (huffman.IsFull()) {
+ int len = strstart - blockStart;
+ if (prevAvailable) {
+ len--;
+ }
+ bool lastBlock = (finish && (lookahead == 0) && !prevAvailable);
+ huffman.FlushBlock(window, blockStart, len, lastBlock);
+ blockStart += len;
+ return !lastBlock;
+ }
+ }
+ return true;
+ }
+
+ #region Instance Fields
+
+ // Hash index of string to be inserted
+ int ins_h;
+
+ /// <summary>
+ /// Hashtable, hashing three characters to an index for window, so
+ /// that window[index]..window[index+2] have this hash code.
+ /// Note that the array should really be unsigned short, so you need
+ /// to and the values with 0xffff.
+ /// </summary>
+ short[] head;
+
+ /// <summary>
+ /// <code>prev[index &amp; WMASK]</code> points to the previous index that has the
+ /// same hash code as the string starting at index. This way
+ /// entries with the same hash code are in a linked list.
+ /// Note that the array should really be unsigned short, so you need
+ /// to and the values with 0xffff.
+ /// </summary>
+ short[] prev;
+
+ int matchStart;
+ // Length of best match
+ int matchLen;
+ // Set if previous match exists
+ bool prevAvailable;
+ int blockStart;
+
+ /// <summary>
+ /// Points to the current character in the window.
+ /// </summary>
+ int strstart;
+
+ /// <summary>
+ /// lookahead is the number of characters starting at strstart in
+ /// window that are valid.
+ /// So window[strstart] until window[strstart+lookahead-1] are valid
+ /// characters.
+ /// </summary>
+ int lookahead;
+
+ /// <summary>
+ /// This array contains the part of the uncompressed stream that
+ /// is of relevance. The current character is indexed by strstart.
+ /// </summary>
+ byte[] window;
+
+ DeflateStrategy strategy;
+ int max_chain, max_lazy, niceLength, goodLength;
+
+ /// <summary>
+ /// The current compression function.
+ /// </summary>
+ int compressionFunction;
+
+ /// <summary>
+ /// The input data for compression.
+ /// </summary>
+ byte[] inputBuf;
+
+ /// <summary>
+ /// The total bytes of input read.
+ /// </summary>
+ long totalIn;
+
+ /// <summary>
+ /// The offset into inputBuf, where input data starts.
+ /// </summary>
+ int inputOff;
+
+ /// <summary>
+ /// The end offset of the input data.
+ /// </summary>
+ int inputEnd;
+
+ DeflaterPending pending;
+ DeflaterHuffman huffman;
+
+ /// <summary>
+ /// The adler checksum
+ /// </summary>
+ Adler32 adler;
+ #endregion
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterHuffman.cs b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterHuffman.cs
new file mode 100644
index 0000000..e94cbd5
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterHuffman.cs
@@ -0,0 +1,881 @@
+// DeflaterHuffman.cs
+//
+// Copyright (C) 2001 Mike Krueger
+// Copyright (C) 2004 John Reilly
+//
+// This file was translated from java, it was part of the GNU Classpath
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+using System;
+
+namespace Plupload.PngEncoder {
+
+ /// <summary>
+ /// This is the DeflaterHuffman class.
+ ///
+ /// This class is <i>not</i> thread safe. This is inherent in the API, due
+ /// to the split of Deflate and SetInput.
+ ///
+ /// author of the original java version : Jochen Hoenicke
+ /// </summary>
+ public class DeflaterHuffman {
+ const int BUFSIZE = 1 << (DeflaterConstants.DEFAULT_MEM_LEVEL + 6);
+ const int LITERAL_NUM = 286;
+
+ // Number of distance codes
+ const int DIST_NUM = 30;
+ // Number of codes used to transfer bit lengths
+ const int BITLEN_NUM = 19;
+
+ // repeat previous bit length 3-6 times (2 bits of repeat count)
+ const int REP_3_6 = 16;
+ // repeat a zero length 3-10 times (3 bits of repeat count)
+ const int REP_3_10 = 17;
+ // repeat a zero length 11-138 times (7 bits of repeat count)
+ const int REP_11_138 = 18;
+
+ const int EOF_SYMBOL = 256;
+
+ // The lengths of the bit length codes are sent in order of decreasing
+ // probability, to avoid transmitting the lengths for unused bit length codes.
+ static readonly int[] BL_ORDER = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
+
+ static readonly byte[] bit4Reverse = {
+ 0,
+ 8,
+ 4,
+ 12,
+ 2,
+ 10,
+ 6,
+ 14,
+ 1,
+ 9,
+ 5,
+ 13,
+ 3,
+ 11,
+ 7,
+ 15
+ };
+
+ static short[] staticLCodes;
+ static byte[] staticLLength;
+ static short[] staticDCodes;
+ static byte[] staticDLength;
+
+ class Tree {
+ #region Instance Fields
+ public short[] freqs;
+
+ public byte[] length;
+
+ public int minNumCodes;
+
+ public int numCodes;
+
+ short[] codes;
+ int[] bl_counts;
+ int maxLength;
+ DeflaterHuffman dh;
+ #endregion
+
+ #region Constructors
+ public Tree(DeflaterHuffman dh, int elems, int minCodes, int maxLength) {
+ this.dh = dh;
+ this.minNumCodes = minCodes;
+ this.maxLength = maxLength;
+ freqs = new short[elems];
+ bl_counts = new int[maxLength];
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Resets the internal state of the tree
+ /// </summary>
+ public void Reset() {
+ for (int i = 0; i < freqs.Length; i++) {
+ freqs[i] = 0;
+ }
+ codes = null;
+ length = null;
+ }
+
+ public void WriteSymbol(int code) {
+ // if (DeflaterConstants.DEBUGGING) {
+ // freqs[code]--;
+ // // Console.Write("writeSymbol("+freqs.length+","+code+"): ");
+ // }
+ dh.pending.WriteBits(codes[code] & 0xffff, length[code]);
+ }
+
+ /// <summary>
+ /// Check that all frequencies are zero
+ /// </summary>
+ /// <exception cref="SharpZipBaseException">
+ /// At least one frequency is non-zero
+ /// </exception>
+ public void CheckEmpty() {
+ bool empty = true;
+ for (int i = 0; i < freqs.Length; i++) {
+ if (freqs[i] != 0) {
+ //Console.WriteLine("freqs[" + i + "] == " + freqs[i]);
+ empty = false;
+ }
+ }
+
+ if (!empty) {
+ throw new Exception("!Empty");
+ }
+ }
+
+ /// <summary>
+ /// Set static codes and length
+ /// </summary>
+ /// <param name="staticCodes">new codes</param>
+ /// <param name="staticLengths">length for new codes</param>
+ public void SetStaticCodes(short[] staticCodes, byte[] staticLengths) {
+ codes = staticCodes;
+ length = staticLengths;
+ }
+
+ /// <summary>
+ /// Build dynamic codes and lengths
+ /// </summary>
+ public void BuildCodes() {
+ int numSymbols = freqs.Length;
+ int[] nextCode = new int[maxLength];
+ int code = 0;
+
+ codes = new short[freqs.Length];
+
+ // if (DeflaterConstants.DEBUGGING) {
+ // //Console.WriteLine("buildCodes: "+freqs.Length);
+ // }
+
+ for (int bits = 0; bits < maxLength; bits++) {
+ nextCode[bits] = code;
+ code += bl_counts[bits] << (15 - bits);
+
+ // if (DeflaterConstants.DEBUGGING) {
+ // //Console.WriteLine("bits: " + ( bits + 1) + " count: " + bl_counts[bits]
+ // +" nextCode: "+code);
+ // }
+ }
+
+#if DebugDeflation
+ if ( DeflaterConstants.DEBUGGING && (code != 65536) )
+ {
+ throw new SharpZipBaseException("Inconsistent bl_counts!");
+ }
+#endif
+ for (int i = 0; i < numCodes; i++) {
+ int bits = length[i];
+ if (bits > 0) {
+
+ // if (DeflaterConstants.DEBUGGING) {
+ // //Console.WriteLine("codes["+i+"] = rev(" + nextCode[bits-1]+"),
+ // +bits);
+ // }
+
+ codes[i] = BitReverse(nextCode[bits - 1]);
+ nextCode[bits - 1] += 1 << (16 - bits);
+ }
+ }
+ }
+
+ public void BuildTree() {
+ int numSymbols = freqs.Length;
+
+ /* heap is a priority queue, sorted by frequency, least frequent
+ * nodes first. The heap is a binary tree, with the property, that
+ * the parent node is smaller than both child nodes. This assures
+ * that the smallest node is the first parent.
+ *
+ * The binary tree is encoded in an array: 0 is root node and
+ * the nodes 2*n+1, 2*n+2 are the child nodes of node n.
+ */
+ int[] heap = new int[numSymbols];
+ int heapLen = 0;
+ int maxCode = 0;
+ for (int n = 0; n < numSymbols; n++) {
+ int freq = freqs[n];
+ if (freq != 0) {
+ // Insert n into heap
+ int pos = heapLen++;
+ int ppos;
+ while (pos > 0 && freqs[heap[ppos = (pos - 1) / 2]] > freq) {
+ heap[pos] = heap[ppos];
+ pos = ppos;
+ }
+ heap[pos] = n;
+
+ maxCode = n;
+ }
+ }
+
+ /* We could encode a single literal with 0 bits but then we
+ * don't see the literals. Therefore we force at least two
+ * literals to avoid this case. We don't care about order in
+ * this case, both literals get a 1 bit code.
+ */
+ while (heapLen < 2) {
+ int node = maxCode < 2 ? ++maxCode : 0;
+ heap[heapLen++] = node;
+ }
+
+ numCodes = Math.Max(maxCode + 1, minNumCodes);
+
+ int numLeafs = heapLen;
+ int[] childs = new int[4 * heapLen - 2];
+ int[] values = new int[2 * heapLen - 1];
+ int numNodes = numLeafs;
+ for (int i = 0; i < heapLen; i++) {
+ int node = heap[i];
+ childs[2 * i] = node;
+ childs[2 * i + 1] = -1;
+ values[i] = freqs[node] << 8;
+ heap[i] = i;
+ }
+
+ /* Construct the Huffman tree by repeatedly combining the least two
+ * frequent nodes.
+ */
+ do {
+ int first = heap[0];
+ int last = heap[--heapLen];
+
+ // Propagate the hole to the leafs of the heap
+ int ppos = 0;
+ int path = 1;
+
+ while (path < heapLen) {
+ if (path + 1 < heapLen && values[heap[path]] > values[heap[path + 1]]) {
+ path++;
+ }
+
+ heap[ppos] = heap[path];
+ ppos = path;
+ path = path * 2 + 1;
+ }
+
+ /* Now propagate the last element down along path. Normally
+ * it shouldn't go too deep.
+ */
+ int lastVal = values[last];
+ while ((path = ppos) > 0 && values[heap[ppos = (path - 1) / 2]] > lastVal) {
+ heap[path] = heap[ppos];
+ }
+ heap[path] = last;
+
+
+ int second = heap[0];
+
+ // Create a new node father of first and second
+ last = numNodes++;
+ childs[2 * last] = first;
+ childs[2 * last + 1] = second;
+ int mindepth = Math.Min(values[first] & 0xff, values[second] & 0xff);
+ values[last] = lastVal = values[first] + values[second] - mindepth + 1;
+
+ // Again, propagate the hole to the leafs
+ ppos = 0;
+ path = 1;
+
+ while (path < heapLen) {
+ if (path + 1 < heapLen && values[heap[path]] > values[heap[path + 1]]) {
+ path++;
+ }
+
+ heap[ppos] = heap[path];
+ ppos = path;
+ path = ppos * 2 + 1;
+ }
+
+ // Now propagate the new element down along path
+ while ((path = ppos) > 0 && values[heap[ppos = (path - 1) / 2]] > lastVal) {
+ heap[path] = heap[ppos];
+ }
+ heap[path] = last;
+ } while (heapLen > 1);
+
+ if (heap[0] != childs.Length / 2 - 1) {
+ throw new Exception("Heap invariant violated");
+ }
+
+ BuildLength(childs);
+ }
+
+ /// <summary>
+ /// Get encoded length
+ /// </summary>
+ /// <returns>Encoded length, the sum of frequencies * lengths</returns>
+ public int GetEncodedLength() {
+ int len = 0;
+ for (int i = 0; i < freqs.Length; i++) {
+ len += freqs[i] * length[i];
+ }
+ return len;
+ }
+
+ /// <summary>
+ /// Scan a literal or distance tree to determine the frequencies of the codes
+ /// in the bit length tree.
+ /// </summary>
+ public void CalcBLFreq(Tree blTree) {
+ int max_count; /* max repeat count */
+ int min_count; /* min repeat count */
+ int count; /* repeat count of the current code */
+ int curlen = -1; /* length of current code */
+
+ int i = 0;
+ while (i < numCodes) {
+ count = 1;
+ int nextlen = length[i];
+ if (nextlen == 0) {
+ max_count = 138;
+ min_count = 3;
+ } else {
+ max_count = 6;
+ min_count = 3;
+ if (curlen != nextlen) {
+ blTree.freqs[nextlen]++;
+ count = 0;
+ }
+ }
+ curlen = nextlen;
+ i++;
+
+ while (i < numCodes && curlen == length[i]) {
+ i++;
+ if (++count >= max_count) {
+ break;
+ }
+ }
+
+ if (count < min_count) {
+ blTree.freqs[curlen] += (short) count;
+ } else if (curlen != 0) {
+ blTree.freqs[REP_3_6]++;
+ } else if (count <= 10) {
+ blTree.freqs[REP_3_10]++;
+ } else {
+ blTree.freqs[REP_11_138]++;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Write tree values
+ /// </summary>
+ /// <param name="blTree">Tree to write</param>
+ public void WriteTree(Tree blTree) {
+ int max_count; // max repeat count
+ int min_count; // min repeat count
+ int count; // repeat count of the current code
+ int curlen = -1; // length of current code
+
+ int i = 0;
+ while (i < numCodes) {
+ count = 1;
+ int nextlen = length[i];
+ if (nextlen == 0) {
+ max_count = 138;
+ min_count = 3;
+ } else {
+ max_count = 6;
+ min_count = 3;
+ if (curlen != nextlen) {
+ blTree.WriteSymbol(nextlen);
+ count = 0;
+ }
+ }
+ curlen = nextlen;
+ i++;
+
+ while (i < numCodes && curlen == length[i]) {
+ i++;
+ if (++count >= max_count) {
+ break;
+ }
+ }
+
+ if (count < min_count) {
+ while (count-- > 0) {
+ blTree.WriteSymbol(curlen);
+ }
+ } else if (curlen != 0) {
+ blTree.WriteSymbol(REP_3_6);
+ dh.pending.WriteBits(count - 3, 2);
+ } else if (count <= 10) {
+ blTree.WriteSymbol(REP_3_10);
+ dh.pending.WriteBits(count - 3, 3);
+ } else {
+ blTree.WriteSymbol(REP_11_138);
+ dh.pending.WriteBits(count - 11, 7);
+ }
+ }
+ }
+
+ void BuildLength(int[] childs) {
+ this.length = new byte[freqs.Length];
+ int numNodes = childs.Length / 2;
+ int numLeafs = (numNodes + 1) / 2;
+ int overflow = 0;
+
+ for (int i = 0; i < maxLength; i++) {
+ bl_counts[i] = 0;
+ }
+
+ // First calculate optimal bit lengths
+ int[] lengths = new int[numNodes];
+ lengths[numNodes - 1] = 0;
+
+ for (int i = numNodes - 1; i >= 0; i--) {
+ if (childs[2 * i + 1] != -1) {
+ int bitLength = lengths[i] + 1;
+ if (bitLength > maxLength) {
+ bitLength = maxLength;
+ overflow++;
+ }
+ lengths[childs[2 * i]] = lengths[childs[2 * i + 1]] = bitLength;
+ } else {
+ // A leaf node
+ int bitLength = lengths[i];
+ bl_counts[bitLength - 1]++;
+ this.length[childs[2 * i]] = (byte) lengths[i];
+ }
+ }
+
+ // if (DeflaterConstants.DEBUGGING) {
+ // //Console.WriteLine("Tree "+freqs.Length+" lengths:");
+ // for (int i=0; i < numLeafs; i++) {
+ // //Console.WriteLine("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]
+ // + " len: "+length[childs[2*i]]);
+ // }
+ // }
+
+ if (overflow == 0) {
+ return;
+ }
+
+ int incrBitLen = maxLength - 1;
+ do {
+ // Find the first bit length which could increase:
+ while (bl_counts[--incrBitLen] == 0)
+ ;
+
+ // Move this node one down and remove a corresponding
+ // number of overflow nodes.
+ do {
+ bl_counts[incrBitLen]--;
+ bl_counts[++incrBitLen]++;
+ overflow -= 1 << (maxLength - 1 - incrBitLen);
+ } while (overflow > 0 && incrBitLen < maxLength - 1);
+ } while (overflow > 0);
+
+ /* We may have overshot above. Move some nodes from maxLength to
+ * maxLength-1 in that case.
+ */
+ bl_counts[maxLength - 1] += overflow;
+ bl_counts[maxLength - 2] -= overflow;
+
+ /* Now recompute all bit lengths, scanning in increasing
+ * frequency. It is simpler to reconstruct all lengths instead of
+ * fixing only the wrong ones. This idea is taken from 'ar'
+ * written by Haruhiko Okumura.
+ *
+ * The nodes were inserted with decreasing frequency into the childs
+ * array.
+ */
+ int nodePtr = 2 * numLeafs;
+ for (int bits = maxLength; bits != 0; bits--) {
+ int n = bl_counts[bits - 1];
+ while (n > 0) {
+ int childPtr = 2 * childs[nodePtr++];
+ if (childs[childPtr + 1] == -1) {
+ // We found another leaf
+ length[childs[childPtr]] = (byte) bits;
+ n--;
+ }
+ }
+ }
+ // if (DeflaterConstants.DEBUGGING) {
+ // //Console.WriteLine("*** After overflow elimination. ***");
+ // for (int i=0; i < numLeafs; i++) {
+ // //Console.WriteLine("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]
+ // + " len: "+length[childs[2*i]]);
+ // }
+ // }
+ }
+
+ }
+
+ #region Instance Fields
+ /// <summary>
+ /// Pending buffer to use
+ /// </summary>
+ public DeflaterPending pending;
+
+ Tree literalTree;
+ Tree distTree;
+ Tree blTree;
+
+ // Buffer for distances
+ short[] d_buf;
+ byte[] l_buf;
+ int last_lit;
+ int extra_bits;
+ #endregion
+
+ static DeflaterHuffman() {
+ // See RFC 1951 3.2.6
+ // Literal codes
+ staticLCodes = new short[LITERAL_NUM];
+ staticLLength = new byte[LITERAL_NUM];
+
+ int i = 0;
+ while (i < 144) {
+ staticLCodes[i] = BitReverse((0x030 + i) << 8);
+ staticLLength[i++] = 8;
+ }
+
+ while (i < 256) {
+ staticLCodes[i] = BitReverse((0x190 - 144 + i) << 7);
+ staticLLength[i++] = 9;
+ }
+
+ while (i < 280) {
+ staticLCodes[i] = BitReverse((0x000 - 256 + i) << 9);
+ staticLLength[i++] = 7;
+ }
+
+ while (i < LITERAL_NUM) {
+ staticLCodes[i] = BitReverse((0x0c0 - 280 + i) << 8);
+ staticLLength[i++] = 8;
+ }
+
+ // Distance codes
+ staticDCodes = new short[DIST_NUM];
+ staticDLength = new byte[DIST_NUM];
+ for (i = 0; i < DIST_NUM; i++) {
+ staticDCodes[i] = BitReverse(i << 11);
+ staticDLength[i] = 5;
+ }
+ }
+
+ /// <summary>
+ /// Construct instance with pending buffer
+ /// </summary>
+ /// <param name="pending">Pending buffer to use</param>
+ public DeflaterHuffman(DeflaterPending pending) {
+ this.pending = pending;
+
+ literalTree = new Tree(this, LITERAL_NUM, 257, 15);
+ distTree = new Tree(this, DIST_NUM, 1, 15);
+ blTree = new Tree(this, BITLEN_NUM, 4, 7);
+
+ d_buf = new short[BUFSIZE];
+ l_buf = new byte[BUFSIZE];
+ }
+
+ /// <summary>
+ /// Reset internal state
+ /// </summary>
+ public void Reset() {
+ last_lit = 0;
+ extra_bits = 0;
+ literalTree.Reset();
+ distTree.Reset();
+ blTree.Reset();
+ }
+
+ /// <summary>
+ /// Write all trees to pending buffer
+ /// </summary>
+ /// <param name="blTreeCodes">The number/rank of treecodes to send.</param>
+ public void SendAllTrees(int blTreeCodes) {
+ blTree.BuildCodes();
+ literalTree.BuildCodes();
+ distTree.BuildCodes();
+ pending.WriteBits(literalTree.numCodes - 257, 5);
+ pending.WriteBits(distTree.numCodes - 1, 5);
+ pending.WriteBits(blTreeCodes - 4, 4);
+ for (int rank = 0; rank < blTreeCodes; rank++) {
+ pending.WriteBits(blTree.length[BL_ORDER[rank]], 3);
+ }
+ literalTree.WriteTree(blTree);
+ distTree.WriteTree(blTree);
+
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING) {
+ blTree.CheckEmpty();
+ }
+#endif
+ }
+
+ /// <summary>
+ /// Compress current buffer writing data to pending buffer
+ /// </summary>
+ public void CompressBlock() {
+ for (int i = 0; i < last_lit; i++) {
+ int litlen = l_buf[i] & 0xff;
+ int dist = d_buf[i];
+ if (dist-- != 0) {
+ // if (DeflaterConstants.DEBUGGING) {
+ // Console.Write("["+(dist+1)+","+(litlen+3)+"]: ");
+ // }
+
+ int lc = Lcode(litlen);
+ literalTree.WriteSymbol(lc);
+
+ int bits = (lc - 261) / 4;
+ if (bits > 0 && bits <= 5) {
+ pending.WriteBits(litlen & ((1 << bits) - 1), bits);
+ }
+
+ int dc = Dcode(dist);
+ distTree.WriteSymbol(dc);
+
+ bits = dc / 2 - 1;
+ if (bits > 0) {
+ pending.WriteBits(dist & ((1 << bits) - 1), bits);
+ }
+ } else {
+ // if (DeflaterConstants.DEBUGGING) {
+ // if (litlen > 32 && litlen < 127) {
+ // Console.Write("("+(char)litlen+"): ");
+ // } else {
+ // Console.Write("{"+litlen+"}: ");
+ // }
+ // }
+ literalTree.WriteSymbol(litlen);
+ }
+ }
+
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING) {
+ Console.Write("EOF: ");
+ }
+#endif
+ literalTree.WriteSymbol(EOF_SYMBOL);
+
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING) {
+ literalTree.CheckEmpty();
+ distTree.CheckEmpty();
+ }
+#endif
+ }
+
+ /// <summary>
+ /// Flush block to output with no compression
+ /// </summary>
+ /// <param name="stored">Data to write</param>
+ /// <param name="storedOffset">Index of first byte to write</param>
+ /// <param name="storedLength">Count of bytes to write</param>
+ /// <param name="lastBlock">True if this is the last block</param>
+ public void FlushStoredBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock) {
+#if DebugDeflation
+ // if (DeflaterConstants.DEBUGGING) {
+ // //Console.WriteLine("Flushing stored block "+ storedLength);
+ // }
+#endif
+ pending.WriteBits((DeflaterConstants.STORED_BLOCK << 1) + (lastBlock ? 1 : 0), 3);
+ pending.AlignToByte();
+ pending.WriteShort(storedLength);
+ pending.WriteShort(~storedLength);
+ pending.WriteBlock(stored, storedOffset, storedLength);
+ Reset();
+ }
+
+ /// <summary>
+ /// Flush block to output with compression
+ /// </summary>
+ /// <param name="stored">Data to flush</param>
+ /// <param name="storedOffset">Index of first byte to flush</param>
+ /// <param name="storedLength">Count of bytes to flush</param>
+ /// <param name="lastBlock">True if this is the last block</param>
+ public void FlushBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock) {
+ literalTree.freqs[EOF_SYMBOL]++;
+
+ // Build trees
+ literalTree.BuildTree();
+ distTree.BuildTree();
+
+ // Calculate bitlen frequency
+ literalTree.CalcBLFreq(blTree);
+ distTree.CalcBLFreq(blTree);
+
+ // Build bitlen tree
+ blTree.BuildTree();
+
+ int blTreeCodes = 4;
+ for (int i = 18; i > blTreeCodes; i--) {
+ if (blTree.length[BL_ORDER[i]] > 0) {
+ blTreeCodes = i + 1;
+ }
+ }
+ int opt_len = 14 + blTreeCodes * 3 + blTree.GetEncodedLength() +
+ literalTree.GetEncodedLength() + distTree.GetEncodedLength() +
+ extra_bits;
+
+ int static_len = extra_bits;
+ for (int i = 0; i < LITERAL_NUM; i++) {
+ static_len += literalTree.freqs[i] * staticLLength[i];
+ }
+ for (int i = 0; i < DIST_NUM; i++) {
+ static_len += distTree.freqs[i] * staticDLength[i];
+ }
+ if (opt_len >= static_len) {
+ // Force static trees
+ opt_len = static_len;
+ }
+
+ if (storedOffset >= 0 && storedLength + 4 < opt_len >> 3) {
+ // Store Block
+
+ // if (DeflaterConstants.DEBUGGING) {
+ // //Console.WriteLine("Storing, since " + storedLength + " < " + opt_len
+ // + " <= " + static_len);
+ // }
+ FlushStoredBlock(stored, storedOffset, storedLength, lastBlock);
+ } else if (opt_len == static_len) {
+ // Encode with static tree
+ pending.WriteBits((DeflaterConstants.STATIC_TREES << 1) + (lastBlock ? 1 : 0), 3);
+ literalTree.SetStaticCodes(staticLCodes, staticLLength);
+ distTree.SetStaticCodes(staticDCodes, staticDLength);
+ CompressBlock();
+ Reset();
+ } else {
+ // Encode with dynamic tree
+ pending.WriteBits((DeflaterConstants.DYN_TREES << 1) + (lastBlock ? 1 : 0), 3);
+ SendAllTrees(blTreeCodes);
+ CompressBlock();
+ Reset();
+ }
+ }
+
+ /// <summary>
+ /// Get value indicating if internal buffer is full
+ /// </summary>
+ /// <returns>true if buffer is full</returns>
+ public bool IsFull() {
+ return last_lit >= BUFSIZE;
+ }
+
+ /// <summary>
+ /// Add literal to buffer
+ /// </summary>
+ /// <param name="literal">Literal value to add to buffer.</param>
+ /// <returns>Value indicating internal buffer is full</returns>
+ public bool TallyLit(int literal) {
+ // if (DeflaterConstants.DEBUGGING) {
+ // if (lit > 32 && lit < 127) {
+ // //Console.WriteLine("("+(char)lit+")");
+ // } else {
+ // //Console.WriteLine("{"+lit+"}");
+ // }
+ // }
+ d_buf[last_lit] = 0;
+ l_buf[last_lit++] = (byte) literal;
+ literalTree.freqs[literal]++;
+ return IsFull();
+ }
+
+ /// <summary>
+ /// Add distance code and length to literal and distance trees
+ /// </summary>
+ /// <param name="distance">Distance code</param>
+ /// <param name="length">Length</param>
+ /// <returns>Value indicating if internal buffer is full</returns>
+ public bool TallyDist(int distance, int length) {
+ // if (DeflaterConstants.DEBUGGING) {
+ // //Console.WriteLine("[" + distance + "," + length + "]");
+ // }
+
+ d_buf[last_lit] = (short) distance;
+ l_buf[last_lit++] = (byte) (length - 3);
+
+ int lc = Lcode(length - 3);
+ literalTree.freqs[lc]++;
+ if (lc >= 265 && lc < 285) {
+ extra_bits += (lc - 261) / 4;
+ }
+
+ int dc = Dcode(distance - 1);
+ distTree.freqs[dc]++;
+ if (dc >= 4) {
+ extra_bits += dc / 2 - 1;
+ }
+ return IsFull();
+ }
+
+
+ /// <summary>
+ /// Reverse the bits of a 16 bit value.
+ /// </summary>
+ /// <param name="toReverse">Value to reverse bits</param>
+ /// <returns>Value with bits reversed</returns>
+ public static short BitReverse(int toReverse) {
+ return (short) (bit4Reverse[toReverse & 0xF] << 12 |
+ bit4Reverse[(toReverse >> 4) & 0xF] << 8 |
+ bit4Reverse[(toReverse >> 8) & 0xF] << 4 |
+ bit4Reverse[toReverse >> 12]);
+ }
+
+ static int Lcode(int length) {
+ if (length == 255) {
+ return 285;
+ }
+
+ int code = 257;
+ while (length >= 8) {
+ code += 4;
+ length >>= 1;
+ }
+ return code + length;
+ }
+
+ static int Dcode(int distance) {
+ int code = 0;
+ while (distance >= 4) {
+ code += 2;
+ distance >>= 1;
+ }
+ return code + distance;
+ }
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterOutputStream.cs b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterOutputStream.cs
new file mode 100644
index 0000000..4556487
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterOutputStream.cs
@@ -0,0 +1,469 @@
+// DeflaterOutputStream.cs
+//
+// Copyright (C) 2001 Mike Krueger
+//
+// This file was translated from java, it was part of the GNU Classpath
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+using System;
+using System.IO;
+
+namespace Plupload.PngEncoder {
+ /// <summary>
+ /// A special stream deflating or compressing the bytes that are
+ /// written to it. It uses a Deflater to perform actual deflating.<br/>
+ /// Authors of the original java version : Tom Tromey, Jochen Hoenicke
+ /// </summary>
+ public class DeflaterOutputStream : Stream {
+ #region Constructors
+ /// <summary>
+ /// Creates a new DeflaterOutputStream with a default Deflater and default buffer size.
+ /// </summary>
+ /// <param name="baseOutputStream">
+ /// the output stream where deflated output should be written.
+ /// </param>
+ public DeflaterOutputStream(Stream baseOutputStream)
+ : this(baseOutputStream, new Deflater(), 512) {
+ }
+
+ /// <summary>
+ /// Creates a new DeflaterOutputStream with the given Deflater and
+ /// default buffer size.
+ /// </summary>
+ /// <param name="baseOutputStream">
+ /// the output stream where deflated output should be written.
+ /// </param>
+ /// <param name="deflater">
+ /// the underlying deflater.
+ /// </param>
+ public DeflaterOutputStream(Stream baseOutputStream, Deflater deflater)
+ : this(baseOutputStream, deflater, 512) {
+ }
+
+ /// <summary>
+ /// Creates a new DeflaterOutputStream with the given Deflater and
+ /// buffer size.
+ /// </summary>
+ /// <param name="baseOutputStream">
+ /// The output stream where deflated output is written.
+ /// </param>
+ /// <param name="deflater">
+ /// The underlying deflater to use
+ /// </param>
+ /// <param name="bufferSize">
+ /// The buffer size to use when deflating
+ /// </param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// bufsize is less than or equal to zero.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// baseOutputStream does not support writing
+ /// </exception>
+ /// <exception cref="ArgumentNullException">
+ /// deflater instance is null
+ /// </exception>
+ public DeflaterOutputStream(Stream baseOutputStream, Deflater deflater, int bufferSize) {
+ if (baseOutputStream == null) {
+ throw new ArgumentNullException("baseOutputStream");
+ }
+
+ if (baseOutputStream.CanWrite == false) {
+ throw new ArgumentException("Must support writing", "baseOutputStream");
+ }
+
+ if (deflater == null) {
+ throw new ArgumentNullException("deflater");
+ }
+
+ if (bufferSize <= 0) {
+ throw new ArgumentOutOfRangeException("bufferSize");
+ }
+
+ baseOutputStream_ = baseOutputStream;
+ buffer_ = new byte[bufferSize];
+ deflater_ = deflater;
+ }
+ #endregion
+
+ #region Public API
+ /// <summary>
+ /// Finishes the stream by calling finish() on the deflater.
+ /// </summary>
+ /// <exception cref="SharpZipBaseException">
+ /// Not all input is deflated
+ /// </exception>
+ public virtual void Finish() {
+ deflater_.Finish();
+ while (!deflater_.IsFinished) {
+ int len = deflater_.Deflate(buffer_, 0, buffer_.Length);
+ if (len <= 0) {
+ break;
+ }
+
+ if (keys != null) {
+ EncryptBlock(buffer_, 0, len);
+ }
+
+ baseOutputStream_.Write(buffer_, 0, len);
+ }
+
+ if (!deflater_.IsFinished) {
+ throw new Exception("Can't deflate all input?");
+ }
+
+ baseOutputStream_.Flush();
+
+
+ if (keys != null) {
+ keys = null;
+ }
+
+ }
+
+ /// <summary>
+ /// Get/set flag indicating ownership of the underlying stream.
+ /// When the flag is true <see cref="Close"></see> will close the underlying stream also.
+ /// </summary>
+ public bool IsStreamOwner {
+ get { return isStreamOwner_; }
+ set { isStreamOwner_ = value; }
+ }
+
+ /// <summary>
+ /// Allows client to determine if an entry can be patched after its added
+ /// </summary>
+ public bool CanPatchEntries {
+ get {
+ return baseOutputStream_.CanSeek;
+ }
+ }
+
+ #endregion
+
+ #region Encryption
+
+ string password;
+
+ uint[] keys;
+
+ /// <summary>
+ /// Get/set the password used for encryption.
+ /// </summary>
+ /// <remarks>When set to null or if the password is empty no encryption is performed</remarks>
+ public string Password {
+ get {
+ return password;
+ }
+ set {
+ if ((value != null) && (value.Length == 0)) {
+ password = null;
+ } else {
+ password = value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Encrypt a block of data
+ /// </summary>
+ /// <param name="buffer">
+ /// Data to encrypt. NOTE the original contents of the buffer are lost
+ /// </param>
+ /// <param name="offset">
+ /// Offset of first byte in buffer to encrypt
+ /// </param>
+ /// <param name="length">
+ /// Number of bytes in buffer to encrypt
+ /// </param>
+ protected void EncryptBlock(byte[] buffer, int offset, int length) {
+ for (int i = offset; i < offset + length; ++i) {
+ byte oldbyte = buffer[i];
+ buffer[i] ^= EncryptByte();
+ UpdateKeys(oldbyte);
+ }
+ }
+
+ /// <summary>
+ /// Encrypt a single byte
+ /// </summary>
+ /// <returns>
+ /// The encrypted value
+ /// </returns>
+ protected byte EncryptByte() {
+ uint temp = ((keys[2] & 0xFFFF) | 2);
+ return (byte) ((temp * (temp ^ 1)) >> 8);
+ }
+
+ /// <summary>
+ /// Update encryption keys
+ /// </summary>
+ protected void UpdateKeys(byte ch) {
+ keys[0] = Crc32.ComputeCrc32(keys[0], ch);
+ keys[1] = keys[1] + (byte) keys[0];
+ keys[1] = keys[1] * 134775813 + 1;
+ keys[2] = Crc32.ComputeCrc32(keys[2], (byte) (keys[1] >> 24));
+ }
+
+ #endregion
+
+ #region Deflation Support
+ /// <summary>
+ /// Deflates everything in the input buffers. This will call
+ /// <code>def.deflate()</code> until all bytes from the input buffers
+ /// are processed.
+ /// </summary>
+ protected void Deflate() {
+ while (!deflater_.IsNeedingInput) {
+ int deflateCount = deflater_.Deflate(buffer_, 0, buffer_.Length);
+
+ if (deflateCount <= 0) {
+ break;
+ }
+
+ if (keys != null) {
+ EncryptBlock(buffer_, 0, deflateCount);
+ }
+
+ baseOutputStream_.Write(buffer_, 0, deflateCount);
+ }
+
+ if (!deflater_.IsNeedingInput) {
+ throw new Exception("DeflaterOutputStream can't deflate all input?");
+ }
+ }
+ #endregion
+
+ #region Stream Overrides
+ /// <summary>
+ /// Gets value indicating stream can be read from
+ /// </summary>
+ public override bool CanRead {
+ get {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating if seeking is supported for this stream
+ /// This property always returns false
+ /// </summary>
+ public override bool CanSeek {
+ get {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Get value indicating if this stream supports writing
+ /// </summary>
+ public override bool CanWrite {
+ get {
+ return baseOutputStream_.CanWrite;
+ }
+ }
+
+ /// <summary>
+ /// Get current length of stream
+ /// </summary>
+ public override long Length {
+ get {
+ return baseOutputStream_.Length;
+ }
+ }
+
+ /// <summary>
+ /// Gets the current position within the stream.
+ /// </summary>
+ /// <exception cref="NotSupportedException">Any attempt to set position</exception>
+ public override long Position {
+ get {
+ return baseOutputStream_.Position;
+ }
+ set {
+ throw new NotSupportedException("Position property not supported");
+ }
+ }
+
+ /// <summary>
+ /// Sets the current position of this stream to the given value. Not supported by this class!
+ /// </summary>
+ /// <param name="offset">The offset relative to the <paramref name="origin"/> to seek.</param>
+ /// <param name="origin">The <see cref="SeekOrigin"/> to seek from.</param>
+ /// <returns>The new position in the stream.</returns>
+ /// <exception cref="NotSupportedException">Any access</exception>
+ public override long Seek(long offset, SeekOrigin origin) {
+ throw new NotSupportedException("DeflaterOutputStream Seek not supported");
+ }
+
+ /// <summary>
+ /// Sets the length of this stream to the given value. Not supported by this class!
+ /// </summary>
+ /// <param name="value">The new stream length.</param>
+ /// <exception cref="NotSupportedException">Any access</exception>
+ public override void SetLength(long value) {
+ throw new NotSupportedException("DeflaterOutputStream SetLength not supported");
+ }
+
+ /// <summary>
+ /// Read a byte from stream advancing position by one
+ /// </summary>
+ /// <returns>The byte read cast to an int. THe value is -1 if at the end of the stream.</returns>
+ /// <exception cref="NotSupportedException">Any access</exception>
+ public override int ReadByte() {
+ throw new NotSupportedException("DeflaterOutputStream ReadByte not supported");
+ }
+
+ /// <summary>
+ /// Read a block of bytes from stream
+ /// </summary>
+ /// <param name="buffer">The buffer to store read data in.</param>
+ /// <param name="offset">The offset to start storing at.</param>
+ /// <param name="count">The maximum number of bytes to read.</param>
+ /// <returns>The actual number of bytes read. Zero if end of stream is detected.</returns>
+ /// <exception cref="NotSupportedException">Any access</exception>
+ public override int Read(byte[] buffer, int offset, int count) {
+ throw new NotSupportedException("DeflaterOutputStream Read not supported");
+ }
+
+ /// <summary>
+ /// Asynchronous reads are not supported a NotSupportedException is always thrown
+ /// </summary>
+ /// <param name="buffer">The buffer to read into.</param>
+ /// <param name="offset">The offset to start storing data at.</param>
+ /// <param name="count">The number of bytes to read</param>
+ /// <param name="callback">The async callback to use.</param>
+ /// <param name="state">The state to use.</param>
+ /// <returns>Returns an <see cref="IAsyncResult"/></returns>
+ /// <exception cref="NotSupportedException">Any access</exception>
+ public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) {
+ throw new NotSupportedException("DeflaterOutputStream BeginRead not currently supported");
+ }
+
+ /// <summary>
+ /// Asynchronous writes arent supported, a NotSupportedException is always thrown
+ /// </summary>
+ /// <param name="buffer">The buffer to write.</param>
+ /// <param name="offset">The offset to begin writing at.</param>
+ /// <param name="count">The number of bytes to write.</param>
+ /// <param name="callback">The <see cref="AsyncCallback"/> to use.</param>
+ /// <param name="state">The state object.</param>
+ /// <returns>Returns an IAsyncResult.</returns>
+ /// <exception cref="NotSupportedException">Any access</exception>
+ public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) {
+ throw new NotSupportedException("BeginWrite is not supported");
+ }
+
+ /// <summary>
+ /// Flushes the stream by calling <see cref="DeflaterOutputStream.Flush">Flush</see> on the deflater and then
+ /// on the underlying stream. This ensures that all bytes are flushed.
+ /// </summary>
+ public override void Flush() {
+ deflater_.Flush();
+ Deflate();
+ baseOutputStream_.Flush();
+ }
+
+ /// <summary>
+ /// Calls <see cref="Finish"/> and closes the underlying
+ /// stream when <see cref="IsStreamOwner"></see> is true.
+ /// </summary>
+ public override void Close() {
+ if (!isClosed_) {
+ isClosed_ = true;
+
+ try {
+ Finish();
+
+ keys = null;
+ } finally {
+ if (isStreamOwner_) {
+ baseOutputStream_.Close();
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Writes a single byte to the compressed output stream.
+ /// </summary>
+ /// <param name="value">
+ /// The byte value.
+ /// </param>
+ public override void WriteByte(byte value) {
+ byte[] b = new byte[1];
+ b[0] = value;
+ Write(b, 0, 1);
+ }
+
+ /// <summary>
+ /// Writes bytes from an array to the compressed stream.
+ /// </summary>
+ /// <param name="buffer">
+ /// The byte array
+ /// </param>
+ /// <param name="offset">
+ /// The offset into the byte array where to start.
+ /// </param>
+ /// <param name="count">
+ /// The number of bytes to write.
+ /// </param>
+ public override void Write(byte[] buffer, int offset, int count) {
+ deflater_.SetInput(buffer, offset, count);
+ Deflate();
+ }
+ #endregion
+
+ #region Instance Fields
+ /// <summary>
+ /// This buffer is used temporarily to retrieve the bytes from the
+ /// deflater and write them to the underlying output stream.
+ /// </summary>
+ byte[] buffer_;
+
+ /// <summary>
+ /// The deflater which is used to deflate the stream.
+ /// </summary>
+ protected Deflater deflater_;
+
+ /// <summary>
+ /// Base stream the deflater depends on.
+ /// </summary>
+ protected Stream baseOutputStream_;
+
+ bool isClosed_;
+
+ bool isStreamOwner_ = true;
+ #endregion
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterPending.cs b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterPending.cs
new file mode 100644
index 0000000..3d5ea36
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/DeflaterPending.cs
@@ -0,0 +1,55 @@
+// DeflaterPending.cs
+//
+// Copyright (C) 2001 Mike Krueger
+// Copyright (C) 2004 John Reilly
+//
+// This file was translated from java, it was part of the GNU Classpath
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+namespace Plupload.PngEncoder {
+
+ /// <summary>
+ /// This class stores the pending output of the Deflater.
+ ///
+ /// author of the original java version : Jochen Hoenicke
+ /// </summary>
+ public class DeflaterPending : PendingBuffer {
+ /// <summary>
+ /// Construct instance with default buffer size
+ /// </summary>
+ public DeflaterPending()
+ : base(DeflaterConstants.PENDING_BUF_SIZE) {
+ }
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/IChecksum.cs b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/IChecksum.cs
new file mode 100644
index 0000000..66c5111
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/IChecksum.cs
@@ -0,0 +1,90 @@
+// IChecksum.cs - Interface to compute a data checksum
+// Copyright (C) 2001 Mike Krueger
+//
+// This file was translated from java, it was part of the GNU Classpath
+// Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+namespace Plupload.PngEncoder {
+
+ /// <summary>
+ /// Interface to compute a data checksum used by checked input/output streams.
+ /// A data checksum can be updated by one byte or with a byte array. After each
+ /// update the value of the current checksum can be returned by calling
+ /// <code>getValue</code>. The complete checksum object can also be reset
+ /// so it can be used again with new data.
+ /// </summary>
+ public interface IChecksum {
+ /// <summary>
+ /// Returns the data checksum computed so far.
+ /// </summary>
+ long Value {
+ get;
+ }
+
+ /// <summary>
+ /// Resets the data checksum as if no update was ever called.
+ /// </summary>
+ void Reset();
+
+ /// <summary>
+ /// Adds one byte to the data checksum.
+ /// </summary>
+ /// <param name = "value">
+ /// the data value to add. The high byte of the int is ignored.
+ /// </param>
+ void Update(int value);
+
+ /// <summary>
+ /// Updates the data checksum with the bytes taken from the array.
+ /// </summary>
+ /// <param name="buffer">
+ /// buffer an array of bytes
+ /// </param>
+ void Update(byte[] buffer);
+
+ /// <summary>
+ /// Adds the byte array to the data checksum.
+ /// </summary>
+ /// <param name = "buffer">
+ /// The buffer which contains the data
+ /// </param>
+ /// <param name = "offset">
+ /// The offset in the buffer where the data starts
+ /// </param>
+ /// <param name = "count">
+ /// the number of data bytes to add.
+ /// </param>
+ void Update(byte[] buffer, int offset, int count);
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/PendingBuffer.cs b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/PendingBuffer.cs
new file mode 100644
index 0000000..d1ef02d
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/PendingBuffer.cs
@@ -0,0 +1,281 @@
+// PendingBuffer.cs
+//
+// Copyright (C) 2001 Mike Krueger
+// Copyright (C) 2004 John Reilly
+//
+// This file was translated from java, it was part of the GNU Classpath
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+using System;
+
+namespace Plupload.PngEncoder {
+
+ /// <summary>
+ /// This class is general purpose class for writing data to a buffer.
+ ///
+ /// It allows you to write bits as well as bytes
+ /// Based on DeflaterPending.java
+ ///
+ /// author of the original java version : Jochen Hoenicke
+ /// </summary>
+ public class PendingBuffer {
+ #region Instance Fields
+ /// <summary>
+ /// Internal work buffer
+ /// </summary>
+ byte[] buffer_;
+
+ int start;
+ int end;
+
+ uint bits;
+ int bitCount;
+ #endregion
+
+ #region Constructors
+ /// <summary>
+ /// construct instance using default buffer size of 4096
+ /// </summary>
+ public PendingBuffer()
+ : this(4096) {
+ }
+
+ /// <summary>
+ /// construct instance using specified buffer size
+ /// </summary>
+ /// <param name="bufferSize">
+ /// size to use for internal buffer
+ /// </param>
+ public PendingBuffer(int bufferSize) {
+ buffer_ = new byte[bufferSize];
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Clear internal state/buffers
+ /// </summary>
+ public void Reset() {
+ start = end = bitCount = 0;
+ }
+
+ /// <summary>
+ /// Write a byte to buffer
+ /// </summary>
+ /// <param name="value">
+ /// The value to write
+ /// </param>
+ public void WriteByte(int value) {
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING && (start != 0) )
+ {
+ throw new SharpZipBaseException("Debug check: start != 0");
+ }
+#endif
+ buffer_[end++] = unchecked((byte) value);
+ }
+
+ /// <summary>
+ /// Write a short value to buffer LSB first
+ /// </summary>
+ /// <param name="value">
+ /// The value to write.
+ /// </param>
+ public void WriteShort(int value) {
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING && (start != 0) )
+ {
+ throw new SharpZipBaseException("Debug check: start != 0");
+ }
+#endif
+ buffer_[end++] = unchecked((byte) value);
+ buffer_[end++] = unchecked((byte) (value >> 8));
+ }
+
+ /// <summary>
+ /// write an integer LSB first
+ /// </summary>
+ /// <param name="value">The value to write.</param>
+ public void WriteInt(int value) {
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING && (start != 0) )
+ {
+ throw new SharpZipBaseException("Debug check: start != 0");
+ }
+#endif
+ buffer_[end++] = unchecked((byte) value);
+ buffer_[end++] = unchecked((byte) (value >> 8));
+ buffer_[end++] = unchecked((byte) (value >> 16));
+ buffer_[end++] = unchecked((byte) (value >> 24));
+ }
+
+ /// <summary>
+ /// Write a block of data to buffer
+ /// </summary>
+ /// <param name="block">data to write</param>
+ /// <param name="offset">offset of first byte to write</param>
+ /// <param name="length">number of bytes to write</param>
+ public void WriteBlock(byte[] block, int offset, int length) {
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING && (start != 0) )
+ {
+ throw new SharpZipBaseException("Debug check: start != 0");
+ }
+#endif
+ System.Array.Copy(block, offset, buffer_, end, length);
+ end += length;
+ }
+
+ /// <summary>
+ /// The number of bits written to the buffer
+ /// </summary>
+ public int BitCount {
+ get {
+ return bitCount;
+ }
+ }
+
+ /// <summary>
+ /// Align internal buffer on a byte boundary
+ /// </summary>
+ public void AlignToByte() {
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING && (start != 0) )
+ {
+ throw new SharpZipBaseException("Debug check: start != 0");
+ }
+#endif
+ if (bitCount > 0) {
+ buffer_[end++] = unchecked((byte) bits);
+ if (bitCount > 8) {
+ buffer_[end++] = unchecked((byte) (bits >> 8));
+ }
+ }
+ bits = 0;
+ bitCount = 0;
+ }
+
+ /// <summary>
+ /// Write bits to internal buffer
+ /// </summary>
+ /// <param name="b">source of bits</param>
+ /// <param name="count">number of bits to write</param>
+ public void WriteBits(int b, int count) {
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING && (start != 0) )
+ {
+ throw new SharpZipBaseException("Debug check: start != 0");
+ }
+
+ // if (DeflaterConstants.DEBUGGING) {
+ // //Console.WriteLine("writeBits("+b+","+count+")");
+ // }
+#endif
+ bits |= (uint) (b << bitCount);
+ bitCount += count;
+ if (bitCount >= 16) {
+ buffer_[end++] = unchecked((byte) bits);
+ buffer_[end++] = unchecked((byte) (bits >> 8));
+ bits >>= 16;
+ bitCount -= 16;
+ }
+ }
+
+ /// <summary>
+ /// Write a short value to internal buffer most significant byte first
+ /// </summary>
+ /// <param name="s">value to write</param>
+ public void WriteShortMSB(int s) {
+#if DebugDeflation
+ if (DeflaterConstants.DEBUGGING && (start != 0) )
+ {
+ throw new SharpZipBaseException("Debug check: start != 0");
+ }
+#endif
+ buffer_[end++] = unchecked((byte) (s >> 8));
+ buffer_[end++] = unchecked((byte) s);
+ }
+
+ /// <summary>
+ /// Indicates if buffer has been flushed
+ /// </summary>
+ public bool IsFlushed {
+ get {
+ return end == 0;
+ }
+ }
+
+ /// <summary>
+ /// Flushes the pending buffer into the given output array. If the
+ /// output array is to small, only a partial flush is done.
+ /// </summary>
+ /// <param name="output">The output array.</param>
+ /// <param name="offset">The offset into output array.</param>
+ /// <param name="length">The maximum number of bytes to store.</param>
+ /// <returns>The number of bytes flushed.</returns>
+ public int Flush(byte[] output, int offset, int length) {
+ if (bitCount >= 8) {
+ buffer_[end++] = unchecked((byte) bits);
+ bits >>= 8;
+ bitCount -= 8;
+ }
+
+ if (length > end - start) {
+ length = end - start;
+ System.Array.Copy(buffer_, start, output, offset, length);
+ start = 0;
+ end = 0;
+ } else {
+ System.Array.Copy(buffer_, start, output, offset, length);
+ start += length;
+ }
+ return length;
+ }
+
+ /// <summary>
+ /// Convert internal buffer to byte array.
+ /// Buffer is empty on completion
+ /// </summary>
+ /// <returns>
+ /// The internal buffer contents converted to a byte array.
+ /// </returns>
+ public byte[] ToByteArray() {
+ byte[] result = new byte[end - start];
+ System.Array.Copy(buffer_, start, result, 0, result.Length);
+ start = 0;
+ end = 0;
+ return result;
+ }
+ }
+}
diff --git a/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/PngEncoder.cs b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/PngEncoder.cs
new file mode 100644
index 0000000..7ef7366
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/PngEncoder/PngEncoder.cs
@@ -0,0 +1,467 @@
+/**
+ * PngEncoder takes a pixel data byte array and creates a byte string which can be saved as a PNG file.
+ *
+ * <p>Thanks to Jay Denny at KeyPoint Software
+ * http://www.keypoint.com/
+ * who let me develop this code on company time.</p>
+ *
+ * <p>You may contact me with (probably very-much-needed) improvements,
+ * comments, and bug fixes at:</p>
+ *
+ * <p><code>david@catcode.com</code></p>
+ *
+ * <p>This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.</p>
+ *
+ * <p>This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.</p>
+ *
+ * <p>You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * A copy of the GNU LGPL may be found at
+ * <code>http://www.gnu.org/copyleft/lesser.html</code></p>
+ *
+ * @author J. David Eisenberg
+ * @version 1.5, 19 Oct 2003
+ *
+ * CHANGES:
+ * --------
+ * 19-Nov-2002 : CODING STYLE CHANGES ONLY (by David Gilbert for Object Refinery Limited);
+ * 19-Sep-2003 : Fix for platforms using EBCDIC (contributed by Paulo Soares);
+ * 19-Oct-2003 : Change private fields to protected fields so that
+ * PngEncoderB can inherit them (JDE)
+ * Fixed bug with calculation of nRows
+ * 2009-12-22 : Ported Java version over to C#.
+ */
+
+using System;
+using System.IO;
+
+namespace Plupload.PngEncoder {
+ public class PngEncoder {
+ /** Constant specifying that alpha channel should be encoded. */
+ public const bool ENCODE_ALPHA = true;
+
+ /** Constant specifying that alpha channel should not be encoded. */
+ public const bool NO_ALPHA = false;
+
+ /** Constants for filter (NONE) */
+ public const int FILTER_NONE = 0;
+
+ /** Constants for filter (SUB) */
+ public const int FILTER_SUB = 1;
+
+ /** Constants for filter (UP) */
+ public const int FILTER_UP = 2;
+
+ /** Constants for filter (LAST) */
+ public const int FILTER_LAST = 2;
+
+ /** IHDR tag. */
+ protected static byte[] IHDR = new byte[] { 73, 72, 68, 82 };
+
+ /** IDAT tag. */
+ protected static byte[] IDAT = new byte[] { 73, 68, 65, 84 };
+
+ /** IEND tag. */
+ protected static byte[] IEND = new byte[] { 73, 69, 78, 68 };
+
+ /** The png bytes. */
+ protected byte[] pngBytes;
+
+ /** The prior row. */
+ protected byte[] priorRow;
+
+ /** The left bytes. */
+ protected byte[] leftBytes;
+
+ /** The width. */
+ protected int width, height;
+
+ /** The byte position. */
+ protected int bytePos, maxPos;
+
+ /** CRC. */
+ protected Crc32 crc = new Crc32();
+
+ /** The CRC value. */
+ protected long crcValue;
+
+ /** Encode alpha? */
+ protected bool encodeAlpha;
+
+ /** The filter type. */
+ protected int filter;
+
+ /** The bytes-per-pixel. */
+ protected int bytesPerPixel;
+
+ /** The compression level. */
+ protected int compressionLevel;
+
+ /** PixelData array to encode */
+ protected int[] pixelData;
+
+ /**
+ * Class constructor specifying Image source to encode, whether to encode alpha, filter to use,
+ * and compression level.
+ *
+ * @param pixel_data A Java Image object
+ * @param encodeAlpha Encode the alpha channel? false=no; true=yes
+ * @param whichFilter 0=none, 1=sub, 2=up
+ * @param compLevel 0..9
+ * @see java.awt.Image
+ */
+ public PngEncoder(int[] pixel_data, int width, int height, bool encodeAlpha, int whichFilter, int compLevel) {
+ this.pixelData = pixel_data;
+ this.width = width;
+ this.height = height;
+ this.encodeAlpha = encodeAlpha;
+
+ this.filter = FILTER_NONE;
+ if (whichFilter <= FILTER_LAST) {
+ this.filter = whichFilter;
+ }
+
+ if (compLevel >= 0 && compLevel <= 9) {
+ this.compressionLevel = compLevel;
+ }
+ }
+
+ /**
+ * Creates an array of bytes that is the PNG equivalent of the current image, specifying
+ * whether to encode alpha or not.
+ *
+ * @param encodeAlpha boolean false=no alpha, true=encode alpha
+ * @return an array of bytes, or null if there was a problem
+ */
+ public byte[] Encode(bool encodeAlpha) {
+ byte[] pngIdBytes = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
+
+ /*
+ * start with an array that is big enough to hold all the pixels
+ * (plus filter bytes), and an extra 200 bytes for header info
+ */
+ pngBytes = new byte[((width + 1) * height * 3) + 200];
+
+ /*
+ * keep track of largest byte written to the array
+ */
+ maxPos = 0;
+
+ bytePos = WriteBytes(pngIdBytes, 0);
+ //hdrPos = bytePos;
+ writeHeader();
+ //dataPos = bytePos;
+ if (WriteImageData()) {
+ writeEnd();
+ pngBytes = ResizeByteArray(pngBytes, maxPos);
+ } else {
+ pngBytes = null;
+ }
+ return pngBytes;
+ }
+
+ /**
+ * Creates an array of bytes that is the PNG equivalent of the current image.
+ * Alpha encoding is determined by its setting in the constructor.
+ *
+ * @return an array of bytes, or null if there was a problem
+ */
+ public byte[] pngEncode() {
+ return Encode(encodeAlpha);
+ }
+
+ /**
+ * Increase or decrease the length of a byte array.
+ *
+ * @param array The original array.
+ * @param newLength The length you wish the new array to have.
+ * @return Array of newly desired length. If shorter than the
+ * original, the trailing elements are truncated.
+ */
+ protected byte[] ResizeByteArray(byte[] array, int newLength) {
+ byte[] newArray = new byte[newLength];
+ int oldLength = array.Length;
+
+ Array.Copy(array, 0, newArray, 0, Math.Min(oldLength, newLength));
+ return newArray;
+ }
+
+ /**
+ * Write an array of bytes into the pngBytes array.
+ * Note: This routine has the side effect of updating
+ * maxPos, the largest element written in the array.
+ * The array is resized by 1000 bytes or the length
+ * of the data to be written, whichever is larger.
+ *
+ * @param data The data to be written into pngBytes.
+ * @param offset The starting point to write to.
+ * @return The next place to be written to in the pngBytes array.
+ */
+ protected int WriteBytes(byte[] data, int offset) {
+ maxPos = Math.Max(maxPos, offset + data.Length);
+ if (data.Length + offset > pngBytes.Length)
+ pngBytes = ResizeByteArray(pngBytes, pngBytes.Length + Math.Max(1000, data.Length));
+
+ Array.Copy(data, 0, pngBytes, offset, data.Length);
+ return offset + data.Length;
+ }
+
+ /**
+ * Write an array of bytes into the pngBytes array, specifying number of bytes to write.
+ * Note: This routine has the side effect of updating
+ * maxPos, the largest element written in the array.
+ * The array is resized by 1000 bytes or the length
+ * of the data to be written, whichever is larger.
+ *
+ * @param data The data to be written into pngBytes.
+ * @param nBytes The number of bytes to be written.
+ * @param offset The starting point to write to.
+ * @return The next place to be written to in the pngBytes array.
+ */
+ protected int WriteBytes(byte[] data, int nBytes, int offset) {
+ maxPos = Math.Max(maxPos, offset + nBytes);
+ if (nBytes + offset > pngBytes.Length)
+ pngBytes = ResizeByteArray(pngBytes, pngBytes.Length + Math.Max(1000, nBytes));
+
+ Array.Copy(data, 0, pngBytes, offset, nBytes);
+ return offset + nBytes;
+ }
+
+ /**
+ * Write a two-byte integer into the pngBytes array at a given position.
+ *
+ * @param n The integer to be written into pngBytes.
+ * @param offset The starting point to write to.
+ * @return The next place to be written to in the pngBytes array.
+ */
+ protected int WriteInt2(int n, int offset) {
+ byte[] temp = { (byte) ((n >> 8) & 0xff), (byte) (n & 0xff) };
+
+ return WriteBytes(temp, offset);
+ }
+
+ /**
+ * Write a four-byte integer into the pngBytes array at a given position.
+ *
+ * @param n The integer to be written into pngBytes.
+ * @param offset The starting point to write to.
+ * @return The next place to be written to in the pngBytes array.
+ */
+ protected int WriteInt4(int n, int offset) {
+ byte[] temp = {(byte) ((n >> 24) & 0xff),
+ (byte) ((n >> 16) & 0xff),
+ (byte) ((n >> 8) & 0xff),
+ (byte) (n & 0xff)};
+
+ return WriteBytes(temp, offset);
+ }
+
+ /**
+ * Write a single byte into the pngBytes array at a given position.
+ *
+ * @param b The integer to be written into pngBytes.
+ * @param offset The starting point to write to.
+ * @return The next place to be written to in the pngBytes array.
+ */
+ protected int WriteByte(int b, int offset) {
+ byte[] temp = { (byte) b };
+
+ return WriteBytes(temp, offset);
+ }
+
+ /**
+ * Write a PNG "IHDR" chunk into the pngBytes array.
+ */
+ protected void writeHeader() {
+ int startPos;
+
+ startPos = bytePos = WriteInt4(13, bytePos);
+
+ bytePos = WriteBytes(IHDR, bytePos);
+ bytePos = WriteInt4(width, bytePos);
+ bytePos = WriteInt4(height, bytePos);
+ bytePos = WriteByte(8, bytePos); // bit depth
+ bytePos = WriteByte((encodeAlpha) ? 6 : 2, bytePos); // direct model
+ bytePos = WriteByte(0, bytePos); // compression method
+ bytePos = WriteByte(0, bytePos); // filter method
+ bytePos = WriteByte(0, bytePos); // no interlace
+
+ crc.Reset();
+ crc.Update(pngBytes, startPos, bytePos - startPos);
+ crcValue = crc.Value;
+
+ bytePos = WriteInt4((int) crcValue, bytePos);
+ }
+
+ /**
+ * Perform "sub" filtering on the given row.
+ * Uses temporary array leftBytes to store the original values
+ * of the previous pixels. The array is 16 bytes long, which
+ * will easily hold two-byte samples plus two-byte alpha.
+ *
+ * @param pixels The array holding the scan lines being built
+ * @param startPos Starting position within pixels of bytes to be filtered.
+ * @param width Width of a scanline in pixels.
+ */
+ protected void FilterSub(byte[] pixels, int startPos, int width) {
+ int i;
+ int offset = bytesPerPixel;
+ int actualStart = startPos + offset;
+ int nBytes = width * bytesPerPixel;
+ int leftInsert = offset;
+ int leftExtract = 0;
+
+ for (i = actualStart; i < startPos + nBytes; i++) {
+ leftBytes[leftInsert] = pixels[i];
+ pixels[i] = (byte) ((pixels[i] - leftBytes[leftExtract]) % 256);
+ leftInsert = (leftInsert + 1) % 0x0f;
+ leftExtract = (leftExtract + 1) % 0x0f;
+ }
+ }
+
+ /**
+ * Perform "up" filtering on the given row.
+ * Side effect: refills the prior row with current row
+ *
+ * @param pixels The array holding the scan lines being built
+ * @param startPos Starting position within pixels of bytes to be filtered.
+ * @param width Width of a scanline in pixels.
+ */
+ protected void FilterUp(byte[] pixels, int startPos, int width) {
+ int i, nBytes;
+ byte currentByte;
+
+ nBytes = width * bytesPerPixel;
+
+ for (i = 0; i < nBytes; i++) {
+ currentByte = pixels[startPos + i];
+ pixels[startPos + i] = (byte) ((pixels[startPos + i] - priorRow[i]) % 256);
+ priorRow[i] = currentByte;
+ }
+ }
+
+ /**
+ * Write the image data into the pngBytes array.
+ * This will write one or more PNG "IDAT" chunks. In order
+ * to conserve memory, this method grabs as many rows as will
+ * fit into 32K bytes, or the whole image; whichever is less.
+ *
+ *
+ * @return true if no errors; false if error grabbing pixels
+ */
+ protected bool WriteImageData() {
+ int rowsLeft = height; // number of rows remaining to write
+ int startRow = 0; // starting row to process this time through
+ int nRows; // how many rows to grab at a time
+
+ byte[] scanLines; // the scan lines to be compressed
+ int scanPos; // where we are in the scan lines
+ int startPos; // where this line's actual pixels start (used for filtering)
+
+ byte[] compressedLines; // the resultant compressed lines
+ int nCompressed; // how big is the compressed area?
+
+ //int depth; // color depth ( handle only 8 or 32 )
+
+ bytesPerPixel = (encodeAlpha) ? 4 : 3;
+
+ Deflater scrunch = new Deflater(compressionLevel);
+ MemoryStream outBytes = new MemoryStream(1024);
+
+ DeflaterOutputStream compBytes = new DeflaterOutputStream(outBytes, scrunch);
+ try {
+ while (rowsLeft > 0) {
+ nRows = Math.Min(32767 / (width * (bytesPerPixel + 1)), rowsLeft);
+ nRows = Math.Max(nRows, 1);
+
+ int[] pixels = new int[width * nRows];
+ Array.Copy(this.pixelData, width * startRow, pixels, 0, width * nRows);
+
+ /*
+ * Create a data chunk. scanLines adds "nRows" for
+ * the filter bytes.
+ */
+ scanLines = new byte[width * nRows * bytesPerPixel + nRows];
+
+ if (filter == FILTER_SUB) {
+ leftBytes = new byte[16];
+ }
+ if (filter == FILTER_UP) {
+ priorRow = new byte[width * bytesPerPixel];
+ }
+
+ scanPos = 0;
+ startPos = 1;
+ for (int i = 0; i < width * nRows; i++) {
+ if (i % width == 0) {
+ scanLines[scanPos++] = (byte) filter;
+ startPos = scanPos;
+ }
+ scanLines[scanPos++] = (byte) ((pixels[i] >> 16) & 0xff);
+ scanLines[scanPos++] = (byte) ((pixels[i] >> 8) & 0xff);
+ scanLines[scanPos++] = (byte) ((pixels[i]) & 0xff);
+ if (encodeAlpha) {
+ scanLines[scanPos++] = (byte) ((pixels[i] >> 24) & 0xff);
+ }
+ if ((i % width == width - 1) && (filter != FILTER_NONE)) {
+ if (filter == FILTER_SUB) {
+ FilterSub(scanLines, startPos, width);
+ }
+ if (filter == FILTER_UP) {
+ FilterUp(scanLines, startPos, width);
+ }
+ }
+ }
+
+ /*
+ * Write these lines to the output area
+ */
+ compBytes.Write(scanLines, 0, scanPos);
+
+ startRow += nRows;
+ rowsLeft -= nRows;
+ }
+ compBytes.Close();
+
+ /*
+ * Write the compressed bytes
+ */
+ compressedLines = outBytes.ToArray();
+ nCompressed = compressedLines.Length;
+
+ crc.Reset();
+ bytePos = WriteInt4(nCompressed, bytePos);
+ bytePos = WriteBytes(IDAT, bytePos);
+ crc.Update(IDAT);
+ bytePos = WriteBytes(compressedLines, nCompressed, bytePos);
+ crc.Update(compressedLines, 0, nCompressed);
+
+ crcValue = crc.Value;
+ bytePos = WriteInt4((int) crcValue, bytePos);
+ scrunch.Finish();
+ return true;
+ } catch {
+ return false;
+ }
+ }
+
+ /**
+ * Write a PNG "IEND" chunk into the pngBytes array.
+ */
+ protected void writeEnd() {
+ bytePos = WriteInt4(0, bytePos);
+ bytePos = WriteBytes(IEND, bytePos);
+ crc.Reset();
+ crc.Update(IEND);
+ crcValue = crc.Value;
+ bytePos = WriteInt4((int) crcValue, bytePos);
+ }
+ }
+} \ No newline at end of file
diff --git a/debian/missing-sources/plupload/csharp/Plupload/Properties/AppManifest.xml b/debian/missing-sources/plupload/csharp/Plupload/Properties/AppManifest.xml
new file mode 100644
index 0000000..1b45a1d
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/Properties/AppManifest.xml
@@ -0,0 +1,6 @@
+<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ ExternalCallersFromCrossDomain="ScriptableOnly">
+ <Deployment.Parts>
+ </Deployment.Parts>
+</Deployment> \ No newline at end of file
diff --git a/debian/missing-sources/plupload/csharp/Plupload/Properties/AssemblyInfo.cs b/debian/missing-sources/plupload/csharp/Plupload/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..005e313
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/Properties/AssemblyInfo.cs
@@ -0,0 +1,45 @@
+/**
+ * $Id: AssemblyInfo.cs 480 2008-10-20 15:37:42Z spocke $
+ *
+ * @package MCManagerCore
+ * @author Moxiecode
+ * @copyright Copyright © 2007, Moxiecode Systems AB, All rights reserved.
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Plupload")]
+[assembly: AssemblyDescription("Multiple upload component.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Moxiecode Systems AB")]
+[assembly: AssemblyProduct("Upload")]
+[assembly: AssemblyCopyright("Copyright © 2009")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("95f0dee8-de7a-46c5-9dcc-0570b0fc4643")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/debian/missing-sources/plupload/csharp/Plupload/Utils/JsonReader.cs b/debian/missing-sources/plupload/csharp/Plupload/Utils/JsonReader.cs
new file mode 100644
index 0000000..659c4fe
--- /dev/null
+++ b/debian/missing-sources/plupload/csharp/Plupload/Utils/JsonReader.cs
@@ -0,0 +1,486 @@
+/*
+ * $Id: JSONReader.cs 9 2007-05-27 10:47:07Z spocke $
+ *
+ * Copyright © 2007, Moxiecode Systems AB, All rights reserved.
+ */
+
+using System;
+using System.IO;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Moxiecode.Plupload.Utils {
+ class Stack {
+ private List<object> items;
+
+ public Stack() {
+ items = new List<object>();
+ }
+
+ public void Push(object item) {
+ items.Add(item);
+ }
+
+ public object Pop() {
+ object item = items[items.Count - 1];
+
+ items.RemoveAt(items.Count - 1);
+
+ return item;
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public enum JsonLocation {
+ /// <summary> </summary>
+ InArray,
+
+ /// <summary> </summary>
+ InObject,
+
+ /// <summary> </summary>
+ Normal
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public enum JsonToken {
+ /// <summary> </summary>
+ Boolean,
+
+ /// <summary> </summary>
+ Integer,
+
+ /// <summary> </summary>
+ String,
+
+ /// <summary> </summary>
+ Null,
+
+ /// <summary> </summary>
+ Float,
+
+ /// <summary> </summary>
+ StartArray,
+
+ /// <summary> </summary>
+ EndArray,
+
+ /// <summary> </summary>
+ PropertyName,
+
+ /// <summary> </summary>
+ StartObject,
+
+ /// <summary> </summary>
+ EndObject
+ }
+
+ /// <summary>
+ /// Description of JSONReader.
+ /// </summary>
+ public class JsonReader {
+ private TextReader reader;
+ private JsonToken token;
+ private object val;
+ private JsonLocation location;
+ private Stack lastLocations;
+ private bool needProp;
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="reader"></param>
+ public JsonReader(TextReader reader) {
+ this.reader = reader;
+ this.val = null;
+ this.token = JsonToken.Null;
+ this.location = JsonLocation.Normal;
+ this.lastLocations = new Stack();
+ this.needProp = false;
+ }
+
+ public static object ParseJson(String json) {
+ JsonReader reader = new JsonReader(new StringReader(json));
+
+ return reader.ReadValue();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public JsonLocation Location {
+ get { return location; }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public JsonToken TokenType {
+ get {
+ return this.token;
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ public object Value {
+ get {
+ return this.val;
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public bool Read() {
+ int chr = this.reader.Read();
+
+ if (chr != -1) {
+ switch ((char) chr) {
+ case '[':
+ this.lastLocations.Push(this.location);
+ this.location = JsonLocation.InArray;
+ this.token = JsonToken.StartArray;
+ this.val = null;
+ this.ReadAway();
+ return true;
+
+ case ']':
+ this.location = (JsonLocation)this.lastLocations.Pop();
+ this.token = JsonToken.EndArray;
+ this.val = null;
+ this.ReadAway();
+
+ if (this.location == JsonLocation.InObject)
+ this.needProp = true;
+
+ return true;
+
+ case '{':
+ this.lastLocations.Push(this.location);
+ this.location = JsonLocation.InObject;
+ this.needProp = true;
+ this.token = JsonToken.StartObject;
+ this.val = null;
+ this.ReadAway();
+ return true;
+
+ case '}':
+ this.location = (JsonLocation) this.lastLocations.Pop();
+ this.token = JsonToken.EndObject;
+ this.val = null;
+ this.ReadAway();
+
+ if (this.location == JsonLocation.InObject)
+ this.needProp = true;
+
+ return true;
+
+ // String
+ case '"':
+ case '\'':
+ return this.ReadString((char) chr);
+
+ // Null
+ case 'n':
+ return this.ReadNull();
+
+ // Bool
+ case 't':
+ case 'f':
+ return this.ReadBool((char) chr);
+
+ default:
+ // Is number
+ if (Char.IsNumber((char) chr) || (char) chr == '-' || (char) chr == '.')
+ return this.ReadNumber((char) chr);
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <returns></returns>
+ public override string ToString() {
+ switch (this.token) {
+ case JsonToken.Boolean:
+ return "[Boolean] = " + ((bool) this.Value ? "true" : "false");
+
+ case JsonToken.EndArray:
+ return "[EndArray]";
+
+ case JsonToken.EndObject:
+ return "[EndObject]";
+
+ case JsonToken.Float:
+ return "[Float] = " + Convert.ToDouble(this.Value);
+
+ case JsonToken.Integer:
+ return "[Integer] = " + ((int) this.Value);
+
+ case JsonToken.Null:
+ return "[Null]";
+
+ case JsonToken.StartArray:
+ return "[StartArray]";
+
+ case JsonToken.StartObject:
+ return "[StartObject]";
+
+ case JsonToken.String:
+ return "[String]" + (string) this.Value;
+
+ case JsonToken.PropertyName:
+ return "[PropertyName]" + (string) this.Value;
+ }
+
+ return base.ToString();
+ }
+
+ #region private methods
+
+ private bool ReadString(char quote) {
+ StringBuilder buff = new StringBuilder();
+ this.token = JsonToken.String;
+ bool endString = false;
+ int chr;
+
+ while ((chr = this.reader.Peek()) != -1) {
+ switch (chr) {
+ case '\\':
+ // Read away slash
+ chr = this.reader.Read();
+
+ // Read escape code
+ chr = this.reader.Read();
+ switch (chr) {
+ case 't':
+ buff.Append('\t');
+ break;
+
+ case 'b':
+ buff.Append('\b');
+ break;
+
+ case 'f':
+ buff.Append('\f');
+ break;
+
+ case 'r':
+ buff.Append('\r');
+ break;
+
+ case 'n':
+ buff.Append('\n');
+ break;
+
+ case 'u':
+ buff.Append((char) Convert.ToInt32(ReadLen(4), 16));
+ break;
+
+ default:
+ buff.Append((char) chr);
+ break;
+ }
+
+ break;
+
+ case '\'':
+ case '"':
+ if (chr == quote)
+ endString = true;
+
+ chr = this.reader.Read();
+ if (chr != -1 && chr != quote)
+ buff.Append((char) chr);
+
+ break;
+
+ default:
+ buff.Append((char) this.reader.Read());
+ break;
+ }
+
+ // String terminated
+ if (endString)
+ break;
+ }
+
+ this.ReadAway();
+
+ this.val = buff.ToString();
+
+ // Needed a property
+ if (this.needProp) {
+ this.token = JsonToken.PropertyName;
+ this.needProp = false;
+ return true;
+ }
+
+ if (this.location == JsonLocation.InObject && !this.needProp)
+ this.needProp = true;
+
+ return true;
+ }
+
+ private bool ReadNull() {
+ this.token = JsonToken.Null;
+ this.val = null;
+
+ this.ReadAway(3); // ull
+ this.ReadAway();
+
+ if (this.location == JsonLocation.InObject && !this.needProp)
+ this.needProp = true;
+
+ return true;
+ }
+
+ private bool ReadNumber(char start) {
+ StringBuilder buff = new StringBuilder();
+ int chr;
+ bool isFloat = false;
+
+ this.token = JsonToken.Integer;
+ buff.Append(start);
+
+ while ((chr = this.reader.Peek()) != -1) {
+ if (Char.IsNumber((char) chr) || (char) chr == '-' || (char) chr == '.') {
+ if (((char) chr) == '.')
+ isFloat = true;
+
+ buff.Append((char) this.reader.Read());
+ } else
+ break;
+ }
+
+ this.ReadAway();
+
+ if (isFloat) {
+ this.token = JsonToken.Float;
+ this.val = Convert.ToDouble(buff.ToString().Replace('.', ','));
+ } else
+ this.val = Convert.ToInt32(buff.ToString());
+
+ if (this.location == JsonLocation.InObject && !this.needProp)
+ this.needProp = true;
+
+ return true;
+ }
+
+ private bool ReadBool(char chr) {
+ this.token = JsonToken.Boolean;
+ this.val = chr == 't';
+
+ if (chr == 't')
+ this.ReadAway(3); // rue
+ else
+ this.ReadAway(4); // alse
+
+ this.ReadAway();
+
+ if (this.location == JsonLocation.InObject && !this.needProp)
+ this.needProp = true;
+
+ return true;
+ }
+
+ private void ReadAway() {
+ int chr;
+
+ while ((chr = this.reader.Peek()) != -1) {
+ if (chr != ':' && chr != ',' && !Char.IsWhiteSpace((char) chr))
+ break;
+
+ this.reader.Read();
+ }
+ }
+
+ private string ReadLen(int num) {
+ StringBuilder buff = new StringBuilder();
+ int chr;
+
+ for (int i=0; i<num && (chr = this.reader.Read()) != -1; i++)
+ buff.Append((char) chr);
+
+ return buff.ToString();
+ }
+
+ private void ReadAway(int num) {
+ for (int i=0; i<num && this.reader.Read() != -1; i++) ;
+ }
+
+ private object ReadValue() {
+ Stack parents = new Stack();
+ object cur = null;
+ string key = null;
+ object obj;
+
+ while (this.Read()) {
+ switch (this.TokenType) {
+ case JsonToken.Boolean:
+ case JsonToken.Integer:
+ case JsonToken.String:
+ case JsonToken.Float:
+ case JsonToken.Null:
+ if (cur is Dictionary<string, object>) {
+ ((Dictionary<string, object>)cur)[key] = this.Value;
+ } else if (cur is List<object>)
+ ((List<object>) cur).Add(this.Value);
+ else
+ return this.Value;
+
+ break;
+
+ case JsonToken.PropertyName:
+ key = (string) this.Value;
+ break;
+
+ case JsonToken.StartArray:
+ case JsonToken.StartObject:
+ if (this.TokenType == JsonToken.StartObject) {
+ obj = new Dictionary<string, object>();
+ } else {
+ obj = new List<object>();
+ }
+
+ if (cur is Dictionary<string, object>) {
+ ((Dictionary<string, object>)cur)[key] = obj;
+ } else if (cur is List<object>) {
+ ((List<object>)cur).Add(obj);
+ }
+
+ parents.Push(cur);
+ cur = obj;
+
+ break;
+
+ case JsonToken.EndArray:
+ case JsonToken.EndObject:
+ obj = parents.Pop();
+
+ if (obj != null)
+ cur = obj;
+
+ break;
+ }
+ }
+
+ return cur;
+ }
+
+ #endregion
+ }
+}
diff --git a/debian/missing-sources/plupload/flash/plupload/Plupload.as3proj b/debian/missing-sources/plupload/flash/plupload/Plupload.as3proj
new file mode 100644
index 0000000..7dc2ba0
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/Plupload.as3proj
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project>
+ <!-- Output SWF options -->
+ <output>
+ <movie disabled="False" />
+ <movie input="" />
+ <movie path="..\..\..\js\plupload.flash.swf" />
+ <movie fps="30" />
+ <movie width="800" />
+ <movie height="600" />
+ <movie version="10" />
+ <movie background="#FFFFFF" />
+ </output>
+ <!-- Other classes to be compiled into your SWF -->
+ <classpaths>
+ <class path="src" />
+ </classpaths>
+ <!-- Build options -->
+ <build>
+ <option accessible="False" />
+ <option allowSourcePathOverlap="False" />
+ <option benchmark="False" />
+ <option es="False" />
+ <option locale="" />
+ <option loadConfig="" />
+ <option optimize="True" />
+ <option showActionScriptWarnings="True" />
+ <option showBindingWarnings="True" />
+ <option showInvalidCSS="True" />
+ <option showDeprecationWarnings="True" />
+ <option showUnusedTypeSelectorWarnings="True" />
+ <option strict="True" />
+ <option useNetwork="True" />
+ <option useResourceBundleMetadata="True" />
+ <option warnings="True" />
+ <option verboseStackTraces="False" />
+ <option linkReport="" />
+ <option loadExterns="" />
+ <option staticLinkRSL="True" />
+ <option additional="" />
+ <option compilerConstants="" />
+ <option customSDK="" />
+ </build>
+ <!-- SWC Include Libraries -->
+ <includeLibraries>
+ <!-- example: <element path="..." /> -->
+ </includeLibraries>
+ <!-- SWC Libraries -->
+ <libraryPaths>
+ <!-- example: <element path="..." /> -->
+ </libraryPaths>
+ <!-- External Libraries -->
+ <externalLibraryPaths>
+ <!-- example: <element path="..." /> -->
+ </externalLibraryPaths>
+ <!-- Runtime Shared Libraries -->
+ <rslPaths>
+ <!-- example: <element path="..." /> -->
+ </rslPaths>
+ <!-- Intrinsic Libraries -->
+ <intrinsics>
+ <!-- example: <element path="..." /> -->
+ </intrinsics>
+ <!-- Assets to embed into the output SWF -->
+ <library>
+ <!-- example: <asset path="..." id="..." update="..." glyphs="..." mode="..." place="..." sharepoint="..." /> -->
+ </library>
+ <!-- Class files to compile (other referenced classes will automatically be included) -->
+ <compileTargets>
+ <compile path="src\com\plupload\Plupload.as" />
+ </compileTargets>
+ <!-- Paths to exclude from the Project Explorer tree -->
+ <hiddenPaths>
+ <!-- example: <hidden path="..." /> -->
+ </hiddenPaths>
+ <!-- Executed before build -->
+ <preBuildCommand />
+ <!-- Executed after build -->
+ <postBuildCommand alwaysRun="False" />
+ <!-- Other project options -->
+ <options>
+ <option showHiddenPaths="False" />
+ <option testMovie="Default" />
+ </options>
+</project> \ No newline at end of file
diff --git a/debian/missing-sources/plupload/flash/plupload/build.sh b/debian/missing-sources/plupload/flash/plupload/build.sh
new file mode 100755
index 0000000..ec0ae46
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/build.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+if [ -z "$FLEX_HOME" ]; then
+ FLEX_HOME=/opt/flex/flex
+fi
+
+export FLEX_HOME
+
+$FLEX_HOME/bin/mxmlc \
+ -compiler.source-path src \
+ -compiler.optimize \
+ -compiler.use-resource-bundle-metadata \
+ -compiler.show-actionscript-warnings \
+ -compiler.show-binding-warnings \
+ -compiler.show-unused-type-selector-warnings \
+ -compiler.strict \
+ -compiler.accessible=false \
+ -use-network \
+ -static-link-runtime-shared-libraries \
+ -output ../../../js/plupload.flash.swf \
+ src/com/plupload/Plupload.as
diff --git a/debian/missing-sources/plupload/flash/plupload/build.vbs b/debian/missing-sources/plupload/flash/plupload/build.vbs
new file mode 100644
index 0000000..51d96cf
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/build.vbs
@@ -0,0 +1,83 @@
+' http://todayguesswhat.blogspot.com.br/2012/08/windows-7-replacement-for.html
+strComputer = "."
+
+Set objFSO = CreateObject("Scripting.FileSystemObject")
+Set objShell = CreateObject("Shell.Application")
+Set objWSShell = CreateObject("WScript.Shell")
+
+strScriptFile = Wscript.ScriptFullName ' C:\plupload-1.x\src\flash\plupload\build.vbs
+Set objFile = objFSO.GetFile(strScriptFile)
+strFolder = objFSO.GetParentFolderName(objFile) ' C:\plupload-1.x\src\flash\plupload
+
+strWorkspace = Mid(strFolder,1,(Len(strFolder) - 19)) 'C:\plupload-1.x (Removed '\src\flash\plupload')
+
+comspec = objWSShell.ExpandEnvironmentStrings("%comspec%")
+
+Set objFile = objShell.BrowseForFolder(0, "Please select the directory that you have extracted Flex SDK:", &H0001) 'Change to &H4000 to show files too
+
+If IsValue(objFile) Then
+ strPathToExileFile = objFile.self.Path
+
+ If Not objFSO.FileExists(strPathToExileFile & "\bin\mxmlc.exe") Then
+ MsgBox strPathToExileFile & "\bin\mxmlc.exe can't be located." & vbcrlf & "Please make sure that you selected the Flex SDK directory.", 48
+ ' http://stackoverflow.com/questions/1686454/run-a-vbscript-from-another-vbscript
+ objWSShell.Run strScriptFile
+ WScript.Quit
+ End If
+Else
+ WScript.Quit
+End If
+
+' I wrote an article on CodeProject about it:
+' http://www.codeproject.com/Tips/507798/Differences-between-Run-and-Exec-VBScript
+
+' ////////////////////////////////////////////////////////
+strExec = Quotes(strPathToExileFile & "\bin\mxmlc.exe") &_
+ " -source-path " & Quotes(strFolder & "\src") &_
+ " -optimize -use-resource-bundle-metadata" &_
+ " -show-actionscript-warnings -show-binding-warnings" &_
+ " -show-unused-type-selector-warnings -strict" &_
+ " -accessible=false -use-network " &_
+ " -static-link-runtime-shared-libraries" &_
+ " -output " & Quotes(strWorkspace & "\js\plupload.flash.swf") &_
+ " " & Quotes(strFolder & "\src\com\plupload\Plupload.as")
+
+'1: Show prompt, True: Wait to finish to continue processing
+'strErrorCode =
+objWSShell.Run(Quotes(strFolder & "\exec.bat") & " " & Quotes(strPathToExileFile),1,True)
+
+'If strErrorCode = 0 Then
+If objFSO.FileExists(strWorkspace & "\js\plupload.flash.swf") Then
+ objWSShell.Exec("explorer.exe /select," & Quotes(strWorkspace & "\js\plupload.flash.swf"))
+Else
+ strResponse = MsgBox("Please make sure you have installed Java JDK (32-bit)." & vbCrLf &_
+ "If Java JDK is installed, you may need to set JAVA_HOME " &_
+ "manually at " & strPathToExileFile & "\bin\jvm.config." & vbCrLf &_
+ "Click YES to read instructions how to do that, or NO to exit this script." & vbCrLf & vbCrLf &_
+ "Command Executed:" & vbCrLf & "(" & strFolder & "\exec.bat) " & vbCrLf & vbCrLf &_
+ strExec,20,"Build failed.")
+
+ If strResponse = vbYes Then
+ objWSShell.Run "iexplore.exe http://stackoverflow.com/questions/3364623/flexsdk-to-compile-mxml-file"
+ Else
+ WScript.Quit
+ End If
+End If
+
+Function IsValue(obj)
+ ' Check whether a value has been returned.
+ Dim tmp
+ On Error Resume Next
+ tmp = " " & obj
+ If Err <> 0 Then
+ IsValue = False
+ Else
+ IsValue = True
+ End If
+ On Error GoTo 0
+End Function
+
+' http://stackoverflow.com/questions/2942554/vbscript-adding-quotes-to-a-string
+Function Quotes(strQuotes)
+ Quotes = chr(34) & strQuotes & chr(34)
+End Function
diff --git a/debian/missing-sources/plupload/flash/plupload/exec.bat b/debian/missing-sources/plupload/flash/plupload/exec.bat
new file mode 100644
index 0000000..fe38e41
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/exec.bat
@@ -0,0 +1,13 @@
+@echo off
+Set dir=%~dp0
+REM flex_dir received by VBScript
+Set flex_dir=%~1
+
+if [%flex_dir%] EQU [] (
+ echo Please do not call this file directly! Use build.vbs
+ pause
+ exit
+)
+
+"%flex_dir%\bin\mxmlc.exe" -source-path "%dir%\src" -optimize -use-resource-bundle-metadata -show-actionscript-warnings -show-binding-warnings -show-unused-type-selector-warnings -strict -accessible=false -use-network -static-link-runtime-shared-libraries -output "%dir:~0,-20%\js\plupload.flash.swf" "%dir%\src\com\plupload\Plupload.as"
+pause
diff --git a/debian/missing-sources/plupload/flash/plupload/src/com/formatlos/BitmapDataUnlimited.as b/debian/missing-sources/plupload/flash/plupload/src/com/formatlos/BitmapDataUnlimited.as
new file mode 100644
index 0000000..38c9291
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/src/com/formatlos/BitmapDataUnlimited.as
@@ -0,0 +1,254 @@
+/*
+Copyright (c) 2008 Martin Raedlinger (mr@formatlos.de)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+package com.formatlos
+{
+ import com.formatlos.events.BitmapDataUnlimitedEvent;
+
+ import flash.display.Bitmap;
+ import flash.display.BitmapData;
+ import flash.display.DisplayObject;
+ import flash.display.IBitmapDrawable;
+ import flash.display.Loader;
+ import flash.events.Event;
+ import flash.events.EventDispatcher;
+ import flash.geom.ColorTransform;
+ import flash.geom.Matrix;
+ import flash.geom.Point;
+ import flash.geom.Rectangle;
+
+ /**
+ * Dispatched when the BitmapData is ready
+ *
+ * @eventType com.formatlos.events.BitmapDataUnlimitedEvent
+ */
+ [Event(name='COMPLETE', type='com.formatlos.events.BitmapDataUnlimitedEvent')]
+
+ /**
+ * Dispatched when the BitmapData can't be created due to memory issues.
+ * watch your system memory and/or System.totalMemory
+ *
+ * @eventType com.formatlos.events.BitmapDataUnlimitedEvent
+ */
+ [Event(name='ERROR', type='com.formatlos.events.BitmapDataUnlimitedEvent')]
+
+ // ---------------------------------------------------------------------------
+
+ /**
+ * The BitmapDataUnlimited Class creates an empty gif image
+ *
+ * @author Martin Raedlinger
+ *
+ * @example
+ * The example shows how to use the BitmapDataUnlimited
+ * <div class="listing">
+ * <pre>
+ *
+ * var bdu:BitmapDataUnlimited = new BitmapDataUnlimited();
+ * bdu.addEventListener(BitmapDataUnlimitedEvent.COMPLETE, onBmpReady);
+ * bdu.create(5000, 5000, true);
+ *
+ * var hugeBitmapData : BitmapData;
+ *
+ * function onBmpReady(event : BitmapDataUnlimitedEvent) : void
+ * {
+ * hugeBitmapData = bdu.bitmapData;
+ *
+ * var rect : Rectangle = new Rectangle(10, 10, 10, 10);
+ *
+ * hugeBitmapData.fillRect(rect, 0xffff0000);
+ * addChild(new Bitmap(hugeBitmapData));
+ *
+ * trace("BitmapData: w=" + hugeBitmapData.width + " h=" + hugeBitmapData.height);
+ * }
+ *
+ * </pre>
+ * </div>
+ *
+ */
+ public class BitmapDataUnlimited extends EventDispatcher
+ {
+ // basically this value is 4096, but take 4000 to have some buffer
+ static private const DRAW_LIMIT : uint = 4000;
+
+ private var _loader : Loader;
+ private var _gif : Gif;
+ private var _fillColor : uint;
+ private var _transparent : Boolean;
+
+
+ // created bitmapData
+ private var _bitmapData : BitmapData;
+
+ /**
+ * Returns the created BitmapData Object
+ *
+ * @return Huge BitmapData
+ */
+ public function get bitmapData() : BitmapData
+ {
+ return _bitmapData;
+ }
+
+
+ /**
+ * Creates a huge BitmapData object.
+ *
+ * @param width The width of the huge BitmapData
+ * @param height The height of the huge BitmapData
+ * @param transparent transparent BitmapData or not
+ * @param fillColor Fill the BitmapData with color
+ */
+ public function create(width_ : int, height_ : int, transparent_ : Boolean = true, fillColor_ : uint = 0xFFFFFF) : void
+ {
+ try
+ {
+ _bitmapData = new BitmapData(width_, height_, transparent_, fillColor_);
+ dispatchComplete();
+ }
+ catch(error : ArgumentError)
+ {
+ if(width_ <= 0 || height_ <= 0)
+ {
+ throw error;
+ }
+ else
+ {
+ _transparent = transparent_;
+ _fillColor = fillColor_;
+
+ _gif = new Gif(width_, height_, transparent_, fillColor_);
+ _loader = new Loader();
+ _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete);
+ _loader.loadBytes(_gif.bytes);
+ }
+ }
+ }
+
+ /**
+ * Bypasses the 4096px limit in BitmapData.draw() and draws the source display object onto the bitmap image.
+ *
+ * @see http://blog.formatlos.de/2008/12/11/bitmapdatadraw-is-limited-to-4096px/
+ *
+ * @param source_ The display object or BitmapData object to draw to the BitmapData object. (The DisplayObject and BitmapData classes implement the IBitmapDrawable interface.)
+ * @param colorTransform_ A ColorTransform object that you use to adjust the color values of the bitmap. If no object is supplied, the bitmap image's colors are not transformed
+ * @param blendMode_ A string value, from the flash.display.BlendMode class, specifying the blend mode to be applied to the resulting bitmap.
+ * @param clipRect_ A Rectangle object that defines the area of the source object to draw. If you do not supply this value, no clipping occurs and the entire source object is drawn.
+ * @param smoothing_ A Boolean value that determines whether a BitmapData object is smoothed
+ */
+ public function draw(source_ : IBitmapDrawable, matrix_ : Matrix = null, colorTransform_ : ColorTransform = null, blendMode_ : String = null, clipRect_:Rectangle = null, smoothing_ : Boolean = false) : void
+ {
+ var srcRect : Rectangle;
+
+ if (source_ is BitmapData) srcRect = (source_ as BitmapData).rect.clone();
+ else if (source_ is DisplayObject) srcRect = (source_ as DisplayObject).getBounds(source_ as DisplayObject);
+
+
+ if(srcRect)
+ {
+ var x : int = (clipRect_) ? clipRect_.x : 0;
+ var y : int = (clipRect_) ? clipRect_.y : 0;
+ var clipWidth : int = (clipRect_) ? clipRect_.right : _bitmapData.width;
+ var clipHeight : int = (clipRect_) ? clipRect_.bottom : _bitmapData.height;
+ var xMax : int = Math.min(srcRect.right, clipWidth);
+ var yMax : int = Math.min(srcRect.bottom, clipHeight);
+ var matrix : Matrix;
+ var chunk : BitmapData;
+ var clip : Rectangle = new Rectangle();
+
+ if(matrix_) {
+ xMax *= matrix_.a;
+ yMax *= matrix_.d;
+ }
+
+ while(x < xMax)
+ {
+ while(y < yMax)
+ {
+ matrix = new Matrix();
+ if(matrix_) {
+ matrix.a = matrix_.a;
+ matrix.d = matrix_.d;
+ }
+ matrix.translate(-x, -y);
+ clip.width = (xMax - x >= DRAW_LIMIT) ? DRAW_LIMIT : xMax - x;
+ clip.height = (yMax - y >= DRAW_LIMIT) ? DRAW_LIMIT : yMax - y ;
+
+ // use source
+ if(x == 0 && y == 0)
+ {
+ _bitmapData.draw(source_, matrix, colorTransform_, blendMode_, clip, smoothing_);
+ }
+ // copy to chunk first
+ else
+ {
+ if(!chunk) chunk = _bitmapData.clone();
+ chunk.fillRect(chunk.rect, (!_transparent) ? _fillColor : 0x00000000 );
+ chunk.draw(source_, matrix, colorTransform_, blendMode_, clip, smoothing_);
+ _bitmapData.copyPixels(chunk, chunk.rect, new Point(x, y), null, null, true);
+
+ }
+
+ y += DRAW_LIMIT;
+ }
+
+ x += DRAW_LIMIT;
+ y = 0;
+ }
+
+ if(chunk)
+ {
+ chunk.dispose();
+ chunk = null;
+ }
+ }
+ }
+
+
+ private function onLoaderComplete(event : Event) : void
+ {
+ var ok:Boolean = true;
+
+ try
+ {
+ _bitmapData = Bitmap(_loader.content).bitmapData.clone();
+ if(!_transparent) _bitmapData.fillRect(_bitmapData.rect, _fillColor);
+ }
+ catch(error : ArgumentError)
+ {
+ ok = false;
+ dispatchEvent(new BitmapDataUnlimitedEvent(BitmapDataUnlimitedEvent.ERROR));
+ }
+
+ _loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoaderComplete);
+ _loader = null;
+
+ if(ok) dispatchComplete();
+ }
+
+ private function dispatchComplete() : void
+ {
+ dispatchEvent(new BitmapDataUnlimitedEvent(BitmapDataUnlimitedEvent.COMPLETE));
+ }
+
+ }
+} \ No newline at end of file
diff --git a/debian/missing-sources/plupload/flash/plupload/src/com/formatlos/Gif.as b/debian/missing-sources/plupload/flash/plupload/src/com/formatlos/Gif.as
new file mode 100644
index 0000000..3921026
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/src/com/formatlos/Gif.as
@@ -0,0 +1,197 @@
+/*
+Copyright (c) 2008 Martin Raedlinger (mr@formatlos.de)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+ */
+
+package com.formatlos
+{
+ import flash.utils.ByteArray;
+
+ /**
+ * The Gif Class creates an empty gif image
+ *
+ * @author Martin Raedlinger
+ */
+ public class Gif
+ {
+ private var _width : int;
+ private var _height : int;
+ private var _colorTable : ByteArray;
+ private var _colorTableSize : int = 7;
+ private var _transparent : Boolean;
+ private var _transparentIndex : int = 0;
+ private var _fillColor : uint;
+
+ // binary gif data
+ private var _binaryGif : ByteArray;
+
+ /**
+ * Returns the created binary gif data
+ *
+ * @return binary gif data
+ */
+ public function get bytes() : ByteArray
+ {
+ return _binaryGif;
+ }
+
+
+ public function Gif(width_ : int, height_ : int, transparent_ : Boolean = false, fillColor_ : uint = 4.294967295E9)
+ {
+ _width = width_;
+ _height = height_;
+ _transparent = transparent_;
+ _fillColor = fillColor_;
+
+ initialize();
+ }
+
+ private function initialize() : void
+ {
+ _binaryGif = new ByteArray();
+
+ writeHeader();
+ writeLogicalScreenDescriptor();
+ writeColorTable();
+ writeGraphicControlExtensionBlock();
+ writeImageBlock();
+ writeTrailer();
+ }
+
+ private function writeHeader() : void
+ {
+ _binaryGif.writeUTFBytes("GIF89a");
+ }
+
+ private function writeLogicalScreenDescriptor() : void
+ {
+ // size
+ writeShort(_width);
+ writeShort(_height);
+
+ // Packed Fields
+ // bit 0: Global Color Table Flag (GCTF)
+ // bit 1..3: Color Resolution
+ // bit 4: Sort Flag to Global Color Table
+ // bit 5..7: Size of Global Color Table: 2^(1+n)
+ _binaryGif.writeByte((0x80 | 0x70 | 0x00 | _colorTableSize));
+ // Background Color Index
+ _binaryGif.writeByte(0);
+ // Pixel Aspect Ratio
+ _binaryGif.writeByte(0); //
+ }
+
+
+ private function writeColorTable() : void
+ {
+ _colorTable = new ByteArray();
+ //_colorTable[0] = 0xFF0000 >> 16;
+ //_colorTable[1] = 0x00FF00 >> 8;
+ //_colorTable[2] = 0x0000FF;
+ _colorTable[0] = _fillColor >> 16 & 0xFF;
+ _colorTable[1] = _fillColor >> 8 & 0xFF;
+ _colorTable[2] = _fillColor & 0xFF;
+
+ _binaryGif.writeBytes(_colorTable, 0, _colorTable.length);
+
+ var i : int = 0;
+ var n : int = (3 * 256) - _colorTable.length;
+
+ while(i < n)
+ {
+ _binaryGif.writeByte(0);
+ ++i;
+ }
+ }
+
+ private function writeGraphicControlExtensionBlock() : void
+ {
+ // Extension Introducer
+ _binaryGif.writeByte(0x21);
+ // Graphic Control Label
+ _binaryGif.writeByte(0xf9);
+ // Block Size
+ _binaryGif.writeByte(4);
+
+
+ var transparent : int;
+ var dispose : int;
+
+ if (_transparent)
+ {
+ transparent = 1;
+ dispose = 2;
+ }
+ else
+ {
+ transparent = 0;
+ dispose = 0;
+ }
+
+ dispose <<= 2;
+
+ // Packed Fields
+ // bit 0..2: Reserved
+ // bit 3..5: Disposal Method
+ // bit 6: User Input Flag
+ // bit 7: Transparent Color Flag
+ _binaryGif.writeByte(0 | dispose | 0 | transparent);
+
+ // Delay Time
+ writeShort(0);
+ // Transparent Color Index
+ _binaryGif.writeByte(_transparentIndex);
+ // Block Terminator
+ _binaryGif.writeByte(0);
+ }
+
+ private function writeImageBlock() : void
+ {
+ //Image Separator
+ _binaryGif.writeByte(0x2c);
+ // Image Left Position
+ writeShort(0);
+ // image position x,y = 0,0
+ // Image Top Position
+ writeShort(0);
+ // Image Width
+ writeShort(_width);
+ // Image Height
+ writeShort(_height);
+ // Packed Fields
+ _binaryGif.writeByte(0);
+ }
+
+
+ private function writeTrailer() : void
+ {
+ _binaryGif.writeByte(0x3b);
+ }
+
+ private function writeShort(pValue : int) : void
+ {
+ _binaryGif.writeByte(pValue & 0xFF);
+ _binaryGif.writeByte((pValue >> 8) & 0xFF);
+ }
+
+
+
+ }
+} \ No newline at end of file
diff --git a/debian/missing-sources/plupload/flash/plupload/src/com/formatlos/events/BitmapDataUnlimitedEvent.as b/debian/missing-sources/plupload/flash/plupload/src/com/formatlos/events/BitmapDataUnlimitedEvent.as
new file mode 100644
index 0000000..1720065
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/src/com/formatlos/events/BitmapDataUnlimitedEvent.as
@@ -0,0 +1 @@
+/* Copyright (c) 2008 Martin Raedlinger (mr@formatlos.de) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package com.formatlos.events { import flash.events.Event; /** * @author Martin Raedlinger */ public class BitmapDataUnlimitedEvent extends Event { public static const COMPLETE : String = "bitmapDataComplete"; public static const ERROR : String = "bitmapDataError"; public function BitmapDataUnlimitedEvent(type : String, bubbles : Boolean = false, cancelable : Boolean = false) { super(type, bubbles, cancelable); } override public function clone() : Event { return new BitmapDataUnlimitedEvent(type, bubbles, cancelable); } } } \ No newline at end of file
diff --git a/debian/missing-sources/plupload/flash/plupload/src/com/mxi/BinaryReader.as b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/BinaryReader.as
new file mode 100644
index 0000000..f440b78
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/BinaryReader.as
@@ -0,0 +1,92 @@
+/**
+ *
+ * Copyright 2011, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+package com.mxi {
+ import flash.utils.ByteArray;
+ import flash.utils.Endian;
+
+ public class BinaryReader extends ByteArray {
+
+ public function init(binData:ByteArray):void {
+ clear();
+ endian = Endian.BIG_ENDIAN;
+ writeBytes(binData);
+ }
+
+ public function II(... args):* {
+ if (!args.length)
+ return endian == Endian.LITTLE_ENDIAN ? true : false;
+ else
+ endian = args[0] == true ? Endian.LITTLE_ENDIAN : Endian.BIG_ENDIAN;
+ }
+
+ public function SEGMENT(... args):ByteArray {
+ var seg:ByteArray = new ByteArray();
+
+ switch (args.length) {
+
+ case 1:
+ position = args[0];
+ readBytes(seg, 0);
+ break;
+
+ case 2:
+ position = args[0];
+ readBytes(seg, 0, args[1]);
+ break;
+
+ case 3:
+ position = args[0] + args[1];
+ readBytes(seg);
+ position = args[0];
+ writeBytes(args[2]);
+ writeBytes(seg);
+ break;
+
+ default:
+ position = 0;
+ readBytes(seg, 0, length);
+ }
+
+ return seg;
+ }
+
+ public function BYTE(idx:int):uint {
+ position = idx;
+ return readUnsignedByte();
+ }
+
+ public function SHORT(idx:int):uint {
+ position = idx;
+ return readUnsignedShort();
+ }
+
+ public function LONG(idx:int, ... args):* {
+ position = idx;
+ if (!args.length)
+ return readUnsignedInt();
+ else
+ writeUnsignedInt(args[0]);
+ }
+
+ public function SLONG(idx:uint):int {
+ position = idx;
+ return readInt();
+ }
+
+ public function STRING(idx:uint, size:uint):String {
+ position = idx;
+ return readUTFBytes(size);
+ }
+
+
+ }
+
+
+}
diff --git a/debian/missing-sources/plupload/flash/plupload/src/com/mxi/CleanEventDispatcher.as b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/CleanEventDispatcher.as
new file mode 100644
index 0000000..3d5818c
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/CleanEventDispatcher.as
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2011, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+package com.mxi
+{
+ import flash.events.EventDispatcher;
+
+ public class CleanEventDispatcher extends EventDispatcher
+ {
+ protected var events:Array = [];
+
+ override public function addEventListener(type:String, callback:Function, useCapture:Boolean = false, priority:int = 0, useWeak:Boolean = false) : void
+ {
+ events.push({
+ type: type,
+ callback: callback
+ });
+
+ /* we pass only required params for simplicity of removal operation, if you need to use other params
+ you will need something more intricate then this one */
+ super.addEventListener(type, callback);
+ }
+
+
+ /* anyone any idea why Flash doesn't have a call like this?.. */
+ public function removeAllEventListeners() : void
+ {
+ var i:int,
+ max:int = events.length;
+ for (i=0; i<max; i++) {
+ removeEventListener(events[i].type, events[i].callback);
+ }
+ events = [];
+ }
+ }
+} \ No newline at end of file
diff --git a/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/ExifParser.as b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/ExifParser.as
new file mode 100644
index 0000000..0370fc6
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/ExifParser.as
@@ -0,0 +1,417 @@
+/**
+ * Copyright 2011, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+package com.mxi.image {
+ import flash.events.EventDispatcher;
+ import flash.utils.ByteArray;
+ import com.mxi.BinaryReader;
+ import flash.external.ExternalInterface;
+
+ public class ExifParser extends EventDispatcher {
+
+ private var data:BinaryReader = new BinaryReader();
+
+ private var offsets:Object = {
+ tiffHeader : 10
+ };
+
+ private var tags:Object = {
+
+ tiff: {
+ 0x0112: 'Orientation',
+ 0x8769: 'ExifIFDPointer',
+ 0x8825: 'GPSInfoIFDPointer'
+ },
+
+ exif: {
+ 0x9000: 'ExifVersion',
+ 0xA001: 'ColorSpace',
+ 0xA002: 'PixelXDimension',
+ 0xA003: 'PixelYDimension',
+ 0x9003: 'DateTimeOriginal',
+ 0x829A: 'ExposureTime',
+ 0x829D: 'FNumber',
+ 0x8827: 'ISOSpeedRatings',
+ 0x9201: 'ShutterSpeedValue',
+ 0x9202: 'ApertureValue' ,
+ 0x9207: 'MeteringMode',
+ 0x9208: 'LightSource',
+ 0x9209: 'Flash',
+ 0xA402: 'ExposureMode',
+ 0xA403: 'WhiteBalance',
+ 0xA406: 'SceneCaptureType',
+ 0xA404: 'DigitalZoomRatio',
+ 0xA408: 'Contrast',
+ 0xA409: 'Saturation',
+ 0xA40A: 'Sharpness'
+ },
+
+ gps: {
+ 0x0000: 'GPSVersionID',
+ 0x0001: 'GPSLatitudeRef',
+ 0x0002: 'GPSLatitude',
+ 0x0003: 'GPSLongitudeRef',
+ 0x0004: 'GPSLongitude'
+ }
+ },
+
+ tagDescs:Object = {
+ 'ColorSpace': {
+ 1: 'sRGB',
+ 0: 'Uncalibrated'
+ },
+ 'MeteringMode': {
+ 0: 'Unknown',
+ 1: 'Average',
+ 2: 'CenterWeightedAverage',
+ 3: 'Spot',
+ 4: 'MultiSpot',
+ 5: 'Pattern',
+ 6: 'Partial',
+ 255: 'Other'
+ },
+ 'LightSource': {
+ 1: 'Daylight',
+ 2: 'Fliorescent',
+ 3: 'Tungsten',
+ 4: 'Flash',
+ 9: 'Fine weather',
+ 10: 'Cloudy weather',
+ 11: 'Shade',
+ 12: 'Daylight fluorescent (D 5700 - 7100K)',
+ 13: 'Day white fluorescent (N 4600 -5400K)',
+ 14: 'Cool white fluorescent (W 3900 - 4500K)',
+ 15: 'White fluorescent (WW 3200 - 3700K)',
+ 17: 'Standard light A',
+ 18: 'Standard light B',
+ 19: 'Standard light C',
+ 20: 'D55',
+ 21: 'D65',
+ 22: 'D75',
+ 23: 'D50',
+ 24: 'ISO studio tungsten',
+ 255: 'Other'
+ },
+ 'Flash': {
+ 0x0000: 'Flash did not fire.',
+ 0x0001: 'Flash fired.',
+ 0x0005: 'Strobe return light not detected.',
+ 0x0007: 'Strobe return light detected.',
+ 0x0009: 'Flash fired, compulsory flash mode',
+ 0x000D: 'Flash fired, compulsory flash mode, return light not detected',
+ 0x000F: 'Flash fired, compulsory flash mode, return light detected',
+ 0x0010: 'Flash did not fire, compulsory flash mode',
+ 0x0018: 'Flash did not fire, auto mode',
+ 0x0019: 'Flash fired, auto mode',
+ 0x001D: 'Flash fired, auto mode, return light not detected',
+ 0x001F: 'Flash fired, auto mode, return light detected',
+ 0x0020: 'No flash function',
+ 0x0041: 'Flash fired, red-eye reduction mode',
+ 0x0045: 'Flash fired, red-eye reduction mode, return light not detected',
+ 0x0047: 'Flash fired, red-eye reduction mode, return light detected',
+ 0x0049: 'Flash fired, compulsory flash mode, red-eye reduction mode',
+ 0x004D: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected',
+ 0x004F: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected',
+ 0x0059: 'Flash fired, auto mode, red-eye reduction mode',
+ 0x005D: 'Flash fired, auto mode, return light not detected, red-eye reduction mode',
+ 0x005F: 'Flash fired, auto mode, return light detected, red-eye reduction mode'
+ },
+ 'ExposureMode': {
+ 0: 'Auto exposure',
+ 1: 'Manual exposure',
+ 2: 'Auto bracket'
+ },
+ 'WhiteBalance': {
+ 0: 'Auto white balance',
+ 1: 'Manual white balance'
+ },
+ 'SceneCaptureType': {
+ 0: 'Standard',
+ 1: 'Landscape',
+ 2: 'Portrait',
+ 3: 'Night scene'
+ },
+ 'Contrast': {
+ 0: 'Normal',
+ 1: 'Soft',
+ 2: 'Hard'
+ },
+ 'Saturation': {
+ 0: 'Normal',
+ 1: 'Low saturation',
+ 2: 'High saturation'
+ },
+ 'Sharpness': {
+ 0: 'Normal',
+ 1: 'Soft',
+ 2: 'Hard'
+ },
+
+ // GPS related
+ 'GPSLatitudeRef': {
+ N: 'North latitude',
+ S: 'South latitude'
+ },
+ 'GPSLongitudeRef': {
+ E: 'East longitude',
+ W: 'West longitude'
+ }
+ };
+
+ public function init(segment:ByteArray):Boolean {
+ // Reset internal data
+ offsets = {
+ tiffHeader: 10
+ };
+
+ if (!segment || !segment.length) {
+ return false;
+ }
+
+ data.init(segment);
+
+ // Check if that's APP1 and that it has EXIF
+ if (data.SHORT(0) === 0xFFE1 && data.STRING(4, 4).toUpperCase() === "EXIF") {
+ return getIFDOffsets();
+ }
+ return false;
+ }
+
+
+ public function EXIF():Object {
+ var Exif:Object;
+
+ if (!offsets.hasOwnProperty('exifIFD') || offsets['exifIFD'] === null) {
+ return null;
+ }
+
+ try { // survive invalid offsets
+ Exif = extractTags(offsets['exifIFD'], tags.exif);
+ } catch (ex:Error) {
+ return null;
+ }
+
+ // fix formatting of some tags
+ if (Exif.hasOwnProperty('ExifVersion') && Exif.ExifVersion is Array) {
+ for (var i:uint = 0, exifVersion:String = ''; i < Exif.ExifVersion.length; i++) {
+ exifVersion += String.fromCharCode(Exif.ExifVersion[i]);
+ }
+ Exif.ExifVersion = exifVersion;
+ }
+
+ return Exif;
+ }
+
+ public function GPS():Object {
+ var Gps:Object;
+
+ if (!offsets.hasOwnProperty('gpsIFD') || offsets['gps'] === null) {
+ return null;
+ }
+
+ try { // survive invalid offsets
+ Gps = extractTags(offsets['gpsIFD'], tags.gps);
+ } catch (ex:Error) {
+ return null;
+ }
+
+ if (Gps.hasOwnProperty('GPSVersionID') && Gps.GPSVersionID is Array) {
+ Gps.GPSVersionID = Gps.GPSVersionID.join('.');
+ }
+
+ return Gps;
+ }
+
+
+ public function setExif(tag:String, value:*) : Boolean {
+ // Right now only setting of width/height is possible
+ if (tag !== 'PixelXDimension' && tag !== 'PixelYDimension') return false;
+
+ return setTag('exif', tag, value);
+ }
+
+
+ public function getBinary():ByteArray {
+ return data.SEGMENT();
+ }
+
+
+ private function isJPEG():Boolean {
+ return data.SHORT(0) == 0xFFD8;
+ }
+
+
+ private function getIFDOffsets():Boolean {
+ var Tiff:Object, idx:uint = offsets.tiffHeader;
+
+ // Set read order of multi-byte data
+ data.II(data.SHORT(idx) == 0x4949);
+
+ // Check if always present bytes are indeed present
+ if (data.SHORT(idx+=2) !== 0x002A) {
+ return false;
+ }
+
+ offsets['IFD0'] = offsets.tiffHeader + data.LONG(idx += 2);
+ Tiff = extractTags(offsets['IFD0'], tags.tiff);
+
+ offsets['exifIFD'] = ('ExifIFDPointer' in Tiff ? offsets.tiffHeader + Tiff.ExifIFDPointer : null);
+ offsets['gpsIFD'] = ('GPSInfoIFDPointer' in Tiff ? offsets.tiffHeader + Tiff.GPSInfoIFDPointer : null);
+
+ return true;
+ }
+
+
+ private function extractTags(IFD_offset:int, tags2extract:Object):Object {
+ var length:uint = data.SHORT(IFD_offset), i:uint, ii:uint,
+ tag:String, type:uint, count:uint, tagOffset:uint, offset:uint, value:*,
+ values:Array = [], hash:Object = {};
+
+ for (i = 0; i < length; i++) {
+ // Set binary reader pointer to beginning of the next tag
+ offset = tagOffset = IFD_offset + 12 * i + 2;
+
+ tag = tags2extract[data.SHORT(offset)];
+
+ if (!tag) {
+ continue; // Not the tag we requested
+ }
+
+ type = data.SHORT(offset+=2);
+ count = data.LONG(offset+=2);
+
+ offset += 4;
+ values = [];
+
+ switch (type) {
+ case 1: // BYTE
+ case 7: // UNDEFINED
+ if (count > 4) {
+ offset = data.LONG(offset) + offsets.tiffHeader;
+ }
+
+ for (ii = 0; ii < count; ii++) {
+ values[ii] = data.BYTE(offset + ii);
+ }
+
+ break;
+
+ case 2: // STRING
+ if (count > 4) {
+ offset = data.LONG(offset) + offsets.tiffHeader;
+ }
+
+ hash[tag] = data.STRING(offset, count - 1);
+
+ continue;
+
+ case 3: // SHORT
+ if (count > 2) {
+ offset = data.LONG(offset) + offsets.tiffHeader;
+ }
+
+ for (ii = 0; ii < count; ii++) {
+ values[ii] = data.SHORT(offset + ii*2);
+ }
+
+ break;
+
+ case 4: // LONG
+ if (count > 1) {
+ offset = data.LONG(offset) + offsets.tiffHeader;
+ }
+
+ for (ii = 0; ii < count; ii++) {
+ values[ii] = data.LONG(offset + ii*4);
+ }
+
+ break;
+
+ case 5: // RATIONAL
+ offset = data.LONG(offset) + offsets.tiffHeader;
+
+ for (ii = 0; ii < count; ii++) {
+ values[ii] = data.LONG(offset + ii*4) / data.LONG(offset + ii*4 + 4);
+ }
+
+ break;
+
+ case 9: // SLONG
+ offset = data.LONG(offset) + offsets.tiffHeader;
+
+ for (ii = 0; ii < count; ii++) {
+ values[ii] = data.SLONG(offset + ii*4);
+ }
+
+ break;
+
+ case 10: // SRATIONAL
+ offset = data.LONG(offset) + offsets.tiffHeader;
+
+ for (ii = 0; ii < count; ii++) {
+ values[ii] = data.SLONG(offset + ii*4) / data.SLONG(offset + ii*4 + 4);
+ }
+
+ break;
+
+ default:
+ continue;
+ }
+
+ value = (count == 1 ? values[0] : values);
+
+ if (tagDescs.hasOwnProperty(tag) && typeof value != 'object') {
+ hash[tag] = tagDescs[tag][value];
+ } else {
+ hash[tag] = value;
+ }
+ }
+
+ return hash;
+ }
+
+
+ // At the moment only setting of simple (LONG) values, that do not require offset recalculation, is supported
+ private function setTag(ifd:String, tag:*, value:*) : Boolean {
+ var offset:*, length:uint, tagOffset:uint, valueOffset:uint = 0, hex:*;
+
+ // If tag name passed translate into hex key
+ if (tag is String) {
+ var tmpTags:Object = tags[ifd.toLowerCase()];
+ for (hex in tmpTags) {
+ if (tmpTags[hex] === tag) {
+ tag = hex;
+ break;
+ }
+ }
+ }
+ offset = offsets[ifd.toLowerCase() + 'IFD'];
+ if (offset === null) {
+ return false;
+ }
+
+ length = data.SHORT(offset);
+
+ for (var i:uint = 0; i < length; i++) {
+ tagOffset = offset + 12 * i + 2;
+
+ if (data.SHORT(tagOffset) == tag) {
+ valueOffset = tagOffset + 8;
+ break;
+ }
+ }
+
+ if (!valueOffset) return false;
+
+ data.LONG(valueOffset, value);
+ return true;
+ }
+
+ }
+
+}
diff --git a/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/Image.as b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/Image.as
new file mode 100644
index 0000000..c1d91c3
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/Image.as
@@ -0,0 +1,216 @@
+/**
+ * Copyright 2011, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+package com.mxi.image
+{
+ import com.formatlos.BitmapDataUnlimited;
+ import com.formatlos.events.BitmapDataUnlimitedEvent;
+ import com.mxi.CleanEventDispatcher;
+ import com.mxi.image.events.ExifParserEvent;
+ import flash.display.BitmapData;
+ import flash.display.IBitmapDrawable;
+ import flash.display.Loader;
+ import flash.events.Event;
+ import flash.geom.Matrix;
+ import flash.utils.ByteArray;
+ import flash.utils.getQualifiedClassName;
+ import mx.graphics.codec.JPEGEncoder;
+ import mx.graphics.codec.PNGEncoder;
+ import com.mxi.image.events.ImageEvent;
+ import flash.system.System;
+ import flash.external.ExternalInterface;
+
+ public class Image extends CleanEventDispatcher
+ {
+ private var _source:ByteArray;
+
+ private var _info:Object = null;
+
+ private var _width:Number;
+ private var _height:Number;
+ private var _quality:Number;
+
+ public static const MAX_WIDTH:uint = 8191;
+ public static const MAX_HEIGHT:uint = 8191;
+
+ private var _loader:Loader;
+ private var _image:*;
+
+ public var imageData:ByteArray;
+
+
+ public function Image(source:ByteArray)
+ {
+ _source = source;
+ super();
+ }
+
+ public function scale(width:* = null, height:* = null, quality:* = null) : void
+ {
+ var info:Object, scale:Number;
+
+ info = _getImageInfo();
+ if (!info) {
+ dispatchEvent(new ImageEvent(ImageEvent.ERROR, ImageEvent.WRONG_FORMAT));
+ return;
+ }
+
+ if (info.width > Image.MAX_WIDTH || info.height > Image.MAX_HEIGHT) {
+ dispatchEvent(new ImageEvent(ImageEvent.ERROR, ImageEvent.OUT_OF_DIMENSIONS));
+ return;
+ }
+
+ _width = width || info.width;
+ _height = height || info.height;
+
+ // we might not need to scale
+ scale = Math.min(_width / info.width, _height / info.height);
+
+ if (scale > 1 && (!quality || info.type != "JPEG")) {
+ dispatchEvent(new ImageEvent(ImageEvent.COMPLETE));
+ return;
+ }
+
+ _quality = quality || 90;
+
+ // scale
+ _loader = new Loader;
+ _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onBitmapDataReady);
+ _loader.loadBytes(_source);
+ }
+
+
+ protected function _getImageInfo() : Object
+ {
+ var type:String;
+
+ if (_info) return _info;
+
+ if (JPEG.test(_source)) {
+ _image = new JPEG(_source);
+ }
+ else if (PNG.test(_source)) {
+ _image = new PNG(_source);
+ }
+
+ if (_image) {
+ _info = _image.info();
+ if (_info) {
+ _info['type'] = getQualifiedClassName(_image).replace(/^.*::/, '');
+ }
+ }
+ return _info;
+ }
+
+
+ protected function onBitmapDataReady(e:Event) : void
+ {
+ var bitmapSource:IBitmapDrawable, output:BitmapData, width:Number, height:Number, scale:Number;
+
+ _loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onBitmapDataReady);
+
+ bitmapSource = e.target.content as IBitmapDrawable;
+
+ width = _info.width;
+ height = _info.height;
+
+ // re-calculate width/height proportionally
+ scale = Math.min(_width / width, _height / height);
+
+ // whatever the case, do not upsize
+ if (scale > 1) {
+ scale = 1;
+ }
+
+ _width = Math.round(width * scale);
+ _height = Math.round(height * scale);
+
+ var prepareBitmap:Function = function(width:Number, height:Number, callback:Function) : void
+ {
+ var bitmapCreator:BitmapDataUnlimited = new BitmapDataUnlimited;
+ bitmapCreator.addEventListener(BitmapDataUnlimitedEvent.COMPLETE, function(e:BitmapDataUnlimitedEvent) : void
+ {
+ callback(bitmapCreator.bitmapData);
+ });
+ bitmapCreator.addEventListener(BitmapDataUnlimitedEvent.ERROR, function(e:BitmapDataUnlimitedEvent) : void
+ {
+ dispatchEvent(new ImageEvent(ImageEvent.ERROR, ImageEvent.OUT_OF_MEMORY));
+ });
+ bitmapCreator.create(width, height, true);
+ };
+
+ var outputScale:Function = function(width:Number, height:Number) : void
+ {
+ prepareBitmap(width, height, function(bitmapData:BitmapData) : void
+ {
+ var scale:Number, matrix:Matrix;
+
+ scale = Math.min(width / output.width, height / output.height);
+
+ matrix = new Matrix;
+ matrix.scale(scale, scale);
+
+ bitmapData.draw(output, matrix, null, null, null, true);
+ output.dispose();
+
+ output = bitmapData;
+ });
+ };
+
+ prepareBitmap(width, height, function(bitmapData:BitmapData) : void
+ {
+ output = bitmapData;
+ output.draw(bitmapSource, null, null, null, null, true);
+
+ while (output.width / 2 > _width) {
+ outputScale(output.width / 2, output.height / 2); // modifies output internally
+ }
+
+ // finalize
+ outputScale(_width, _height);
+
+ // encode
+ if (_info.type == "JPEG") {
+ var headers:Array, exifParser:ExifParser;
+
+ imageData = new JPEGEncoder(_quality).encode(output);
+
+ // transfer headers
+ _image.extractHeaders();
+
+ headers = _image.getHeaders('exif');
+ if (headers.length) {
+ exifParser = new ExifParser;
+ if (exifParser.init(headers[0])) {
+
+ exifParser.setExif('PixelXDimension', _width);
+ exifParser.setExif('PixelYDimension', _height);
+
+ dispatchEvent(new ExifParserEvent(ExifParserEvent.EXIF_DATA, exifParser.EXIF()));
+ dispatchEvent(new ExifParserEvent(ExifParserEvent.GPS_DATA, exifParser.GPS()));
+
+ _image.setHeaders('exif', exifParser.getBinary());
+
+ try {
+ imageData = _image.insertHeaders(imageData);
+ } catch (e:Error) {}
+ }
+ }
+ } else {
+ imageData = new PNGEncoder().encode(output);
+ }
+
+ dispatchEvent(new ImageEvent(ImageEvent.COMPLETE));
+ });
+
+ }
+
+
+ }
+
+} \ No newline at end of file
diff --git a/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/JPEG.as b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/JPEG.as
new file mode 100644
index 0000000..33b0df3
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/JPEG.as
@@ -0,0 +1,186 @@
+/**
+ * Copyright 2011, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+package com.mxi.image
+{
+ import com.mxi.BinaryReader;
+ import flash.external.ExternalInterface;
+ import flash.utils.ByteArray;
+
+ public class JPEG
+ {
+ protected var _markers:Object = {
+ 0xFFE1: {
+ app: 'EXIF',
+ name: 'APP1',
+ signature: "Exif"
+ },
+ 0xFFE2: {
+ app: 'ICC',
+ name: 'APP2',
+ signature: "ICC_PROFILE"
+ },
+ 0xFFED: {
+ app: 'IPTC',
+ name: 'APP13',
+ signature: "Photoshop 3.0"
+ }
+ };
+
+ protected var _headers:Array = [];
+ protected var _br:BinaryReader;
+
+ public function JPEG(binData:ByteArray)
+ {
+ _br = new BinaryReader;
+ _br.init(binData);
+ }
+
+ static public function test(binData:ByteArray) : Boolean
+ {
+ var sign:Array = [ 255, 216 ];
+
+ for (var i:int = sign.length - 1; i >= 0 ; i--) {
+ if (binData[i] != sign[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public function info() : Object
+ {
+ var idx:uint = 0, marker:uint, length:uint;
+
+ // examine all through the end, since some images might have very large APP segments
+ while (idx <= _br.length) {
+ marker = _br.SHORT(idx += 2);
+
+ if (marker >= 0xFFC0 && marker <= 0xFFC3) { // SOFn
+ idx += 5; // marker (2 bytes) + length (2 bytes) + Sample precision (1 byte)
+ return {
+ height: _br.SHORT(idx),
+ width: _br.SHORT(idx += 2)
+ };
+ }
+ length = _br.SHORT(idx += 2);
+ idx += length - 2;
+ }
+
+ return null;
+ }
+
+ public function extractHeaders() : Array
+ {
+ var idx:uint, marker:uint, length:uint;
+
+ idx = 2;
+
+ while (idx <= _br.length) {
+ marker = _br.SHORT(idx);
+
+ // omit RST (restart) markers
+ if (marker >= 0xFFD0 && marker <= 0xFFD7) {
+ idx += 2;
+ continue;
+ }
+
+ // no headers allowed after SOS marker
+ if (marker === 0xFFDA || marker === 0xFFD9) {
+ break;
+ }
+
+ length = _br.SHORT(idx + 2) + 2;
+
+ if (_markers[marker] &&
+ _br.STRING(idx + 4, _markers[marker].signature.length) === _markers[marker].signature) {
+ _headers.push({
+ hex: marker,
+ app: _markers[marker].app.toUpperCase(),
+ name: _markers[marker].name.toUpperCase(),
+ start: idx,
+ length: length,
+ segment: _br.SEGMENT(idx, length)
+ });
+ }
+ idx += length;
+ }
+
+ return _headers;
+ }
+
+ public function getHeaders(app:String = null) : Array
+ {
+ var headers:Array, array:Array = [];
+
+ headers = _headers.length ? _headers : extractHeaders();
+
+ if (!app) {
+ return headers;
+ }
+
+ for (var i:uint = 0, max:uint = headers.length; i < max; i++) {
+ if (headers[i].app === app.toUpperCase()) {
+ array.push(headers[i].segment);
+ }
+ }
+ return array;
+ }
+
+ public function setHeaders(app:String, segment:*) : void
+ {
+ var array:Array = [];
+
+ if (segment is ByteArray) {
+ array.push(segment);
+ } else {
+ array = segment;
+ }
+
+ for (var i:uint = 0, ii:uint = 0, max:uint = _headers.length; i < max; i++) {
+ if (_headers[i].app === app.toUpperCase()) {
+ _headers[i].segment = array[ii];
+ _headers[i].length = array[ii].length;
+ ii++;
+ }
+ if (ii >= array.length) break;
+ }
+ }
+
+ public function insertHeaders(binData:ByteArray, headers:Array = null) : ByteArray
+ {
+ var idx:uint, br:BinaryReader = new BinaryReader;
+
+ if (!headers || !headers.length) {
+ headers = _headers;
+ }
+
+ br.init(binData);
+
+ // Check if data is jpeg
+ if (br.SHORT(0) !== 0xFFD8) {
+ throw new Error("Invalid JPEG");
+ }
+
+ if (headers.length) {
+ idx = br.SHORT(2) == 0xFFE0 ? 4 + br.SHORT(4) : 2;
+
+ for (var i:uint = 0, max:uint = headers.length; i < max; i++) {
+ br.SEGMENT(idx, 0, headers[i].segment);
+ idx += headers[i].length;
+ }
+ }
+ return br.SEGMENT();
+ }
+
+ public function purge() : void
+ {
+ _br.clear();
+ }
+ }
+} \ No newline at end of file
diff --git a/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/PNG.as b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/PNG.as
new file mode 100644
index 0000000..f05c93f
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/PNG.as
@@ -0,0 +1,77 @@
+/**
+ * Copyright 2011, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+package com.mxi.image
+{
+ import com.mxi.BinaryReader;
+ import flash.utils.ByteArray;
+
+ public class PNG
+ {
+ protected var _br:BinaryReader;
+
+ public function PNG(binData:ByteArray)
+ {
+ _br = new BinaryReader;
+ _br.init(binData);
+ }
+
+
+ static public function test(binData:ByteArray) : Boolean
+ {
+ var sign:Array = [ 137, 80, 78, 71, 13, 10, 26, 10 ];
+
+ for (var i:int = sign.length - 1; i >= 0 ; i--) {
+ if (binData[i] != sign[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ public function info() : Object
+ {
+ var chunk:Object, idx:uint;
+
+ chunk = _getChunkAt(8);
+
+ if (chunk.type == 'IHDR') {
+ idx = chunk.start;
+ return {
+ width: _br.LONG(idx),
+ height: _br.LONG(idx += 4)
+ };
+ }
+
+ return null;
+ }
+
+
+ private function _getChunkAt(idx:uint) : Object
+ {
+ var length:uint, type:String, start:uint, CRC:uint;
+
+ length = _br.LONG(idx);
+ type = _br.STRING(idx += 4, 4);
+ start = idx += 4;
+ CRC = _br.LONG(idx + length);
+
+ return {
+ length: length,
+ type: type,
+ start: start,
+ CRC: CRC
+ };
+ }
+
+
+
+ }
+
+} \ No newline at end of file
diff --git a/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/events/ExifParserEvent.as b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/events/ExifParserEvent.as
new file mode 100644
index 0000000..fd611da
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/events/ExifParserEvent.as
@@ -0,0 +1,29 @@
+/**
+ * Copyright 2011, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+package com.mxi.image.events {
+ import flash.events.Event;
+
+ public class ExifParserEvent extends Event {
+
+ public var data:Object;
+
+ public static const EXIF_DATA:String = 'exifdata';
+ public static const GPS_DATA:String = 'gpsdata';
+
+ function ExifParserEvent(type:String, data:Object) {
+ this.data = data;
+ super(type);
+ }
+
+ override public function clone() : Event
+ {
+ return new ExifParserEvent(type, data);
+ }
+ }
+} \ No newline at end of file
diff --git a/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/events/ImageEvent.as b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/events/ImageEvent.as
new file mode 100644
index 0000000..780b655
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/src/com/mxi/image/events/ImageEvent.as
@@ -0,0 +1,36 @@
+/**
+ * Copyright 2011, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+package com.mxi.image.events {
+ import flash.events.Event;
+
+ /**
+ * This class is used for uploads of chunks.
+ */
+ public class ImageEvent extends Event {
+
+ public static const COMPLETE:String = 'imagecomplete';
+ public static const ERROR:String = 'imageerror';
+
+ public static const WRONG_FORMAT:String = '-700';
+ public static const OUT_OF_MEMORY:String = '-701';
+ public static const OUT_OF_DIMENSIONS:String = '-702';
+
+ public var code:String;
+
+ function ImageEvent(type:String, code:String = null) {
+ this.code = code;
+ super(type, false, false);
+ }
+
+ override public function clone() : Event
+ {
+ return new ImageEvent(type, code);
+ }
+ }
+} \ No newline at end of file
diff --git a/debian/missing-sources/plupload/flash/plupload/src/com/plupload/File.as b/debian/missing-sources/plupload/flash/plupload/src/com/plupload/File.as
new file mode 100644
index 0000000..74500d4
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/src/com/plupload/File.as
@@ -0,0 +1,499 @@
+/**
+ * File.as
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+package com.plupload {
+ import com.formatlos.BitmapDataUnlimited;
+ import com.formatlos.events.BitmapDataUnlimitedEvent;
+ import flash.display.Bitmap;
+ import flash.display.BitmapData;
+ import flash.display.IBitmapDrawable;
+ import flash.events.EventDispatcher;
+ import flash.geom.Matrix;
+ import flash.net.FileReference;
+ import flash.events.Event;
+ import flash.events.IOErrorEvent;
+ import flash.events.HTTPStatusEvent;
+ import flash.events.ProgressEvent;
+ import flash.events.SecurityErrorEvent;
+ import flash.events.DataEvent;
+ import flash.net.FileReferenceList;
+ import flash.net.URLLoader;
+ import flash.net.URLRequest;
+ import flash.net.URLRequestHeader;
+ import flash.net.URLRequestMethod;
+ import flash.net.URLStream;
+ import flash.net.URLVariables;
+ import flash.utils.ByteArray;
+ import flash.utils.setTimeout;
+ import flash.external.ExternalInterface;
+ import com.mxi.image.events.ExifParserEvent;
+
+ import com.mxi.image.Image;
+ import com.mxi.image.events.ImageEvent;
+
+
+ /**
+ * Container class for file references, this handles upload logic for individual files.
+ */
+ public class File extends EventDispatcher {
+ // Private fields
+ private var _fileRef:FileReference, _urlStream:URLStream, _cancelled:Boolean;
+ private var _uploadUrl:String, _uploadPath:String, _mimeType:String;
+ private var _id:String, _fileName:String, _size:Number, _imageData:ByteArray;
+ private var _multipart:Boolean, _fileDataName:String, _chunking:Boolean, _chunk:int, _chunks:int, _chunkSize:int, _postvars:Object;
+ private var _headers:Object, _settings:Object;
+ private var _removeAllListeners:Function;
+ private var _removeAllURLStreamListeners:Function;
+
+ /**
+ * Id property of file.
+ */
+ public function get id():String {
+ return this._id;
+ }
+
+ /**
+ * File name for the file.
+ */
+ public function get fileName():String {
+ return this._fileName;
+ }
+
+ /**
+ * File name for the file.
+ */
+ public function set fileName(value:String):void {
+ this._fileName = value;
+ }
+
+ /**
+ * File size property.
+ */
+ public function get size():Number {
+ return this._size;
+ }
+
+ /**
+ * Constructs a new file object.
+ *
+ * @param id Unique indentifier for the file.
+ * @param file_ref File reference for the selected file.
+ */
+ public function File(id:String, file_ref:FileReference) {
+ this._id = id;
+ this._fileRef = file_ref;
+ this._size = file_ref.size;
+ this._fileName = file_ref.name;
+ }
+
+ /**
+ * Cancel current upload.
+ */
+ public function cancelUpload(): void
+ {
+ if (this.canUseSimpleUpload(this._settings)) {
+ this._fileRef.cancel();
+ } else if (!this._urlStream) {
+ // In case of a large file and before _fileRef.load#COMPLETE.
+ // Need to cancel() twice, not sure why.
+ // If single cancel(), #2037 will occurred at _fileRef.load().
+ this._fileRef.cancel();
+ this._fileRef.cancel();
+ this._removeAllListeners();
+ } else if (this._urlStream.connected) {
+ // just in case
+ this._removeAllURLStreamListeners();
+
+ this._urlStream.close();
+
+ // In case of a large file and after the first uploadNextChunk().
+ // #2174 will occur at _fileRef.load() and
+ // #2029 will occur at _urlStream.readUTFBytes as well
+ // after loading file is stopped before _fileRef.load#COMPLETE.
+
+ // Uploaded file will be broken as well if the following line does not exist.
+ this._urlStream = null;
+ }
+ }
+
+ /**
+ * Uploads a the file to the specified url. This method will upload it as a normal
+ * multipart file upload if the file size is smaller than the chunk size. But if the file is to
+ * large it will be chunked into multiple requests.
+ *
+ * @param url Url to upload the file to.
+ * @param settings Settings object.
+ */
+ public function upload(url:String, settings:Object):void {
+ this._settings = settings;
+
+ if (this.canUseSimpleUpload(settings)) {
+ this.simpleUpload(url, settings);
+ } else {
+ this.advancedUpload(url, settings);
+ }
+ }
+
+ // Private methods
+
+ public function canUseSimpleUpload(settings:Object):Boolean {
+ var multipart:Boolean = new Boolean(settings["multipart"]);
+ var resize:Boolean = (settings["width"] || settings["height"] || settings["quality"]);
+ var chunking:Boolean = (settings["chunk_size"] > 0);
+
+ // Check if it's not an image, chunking is disabled, multipart enabled and the ref_upload setting isn't forced
+ return (!(/\.(jpeg|jpg|png)$/i.test(this._fileName)) || !resize) && multipart && !chunking && !settings.urlstream_upload && !settings.headers;
+ }
+
+ public function simpleUpload(url:String, settings:Object):void {
+ var file:File = this, request:URLRequest, postData:URLVariables, fileDataName:String;
+ var onProgress:Function, onUploadComplete:Function, onIOError:Function, onSecurityErrorEvent:Function;
+ var removeAllListeners:Function = function () : void {
+ file._fileRef.removeEventListener(ProgressEvent.PROGRESS, onProgress);
+ file._fileRef.removeEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onUploadComplete);
+ file._fileRef.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
+ file._fileRef.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityErrorEvent);
+ };
+
+ this._removeAllListeners = removeAllListeners;
+
+ file._postvars = settings["multipart_params"];
+ file._chunk = 0;
+ file._chunks = 1;
+
+ postData = new URLVariables();
+
+ file._postvars["name"] = settings["name"];
+
+ for (var key:String in file._postvars) {
+ if (key != 'Filename') { // Flash will add it by itself, so we need to omit potential duplicate
+ postData[key] = file._postvars[key];
+ }
+ }
+
+ request = new URLRequest();
+ request.method = URLRequestMethod.POST;
+ request.url = url;
+ request.data = postData;
+
+ fileDataName = new String(settings["file_data_name"]);
+
+ onUploadComplete = function(e:DataEvent):void {
+ removeAllListeners();
+
+ var pe:ProgressEvent = new ProgressEvent(ProgressEvent.PROGRESS, false, false, file._size, file._size);
+ dispatchEvent(pe);
+
+ // Fake UPLOAD_COMPLETE_DATA event
+ var uploadChunkEvt:UploadChunkEvent = new UploadChunkEvent(
+ UploadChunkEvent.UPLOAD_CHUNK_COMPLETE_DATA,
+ false,
+ false,
+ e.data,
+ file._chunk,
+ file._chunks
+ );
+
+ file._chunk++;
+
+ dispatchEvent(uploadChunkEvt);
+
+ dispatchEvent(e);
+ };
+ file._fileRef.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onUploadComplete);
+
+ // Delegate upload IO errors
+ onIOError = function(e:IOErrorEvent):void {
+ removeAllListeners();
+ dispatchEvent(e);
+ };
+ file._fileRef.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
+
+ // Delegate secuirty errors
+ onSecurityErrorEvent = function(e:SecurityErrorEvent):void {
+ removeAllListeners();
+ dispatchEvent(e);
+ };
+ file._fileRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityErrorEvent);
+
+ // Delegate progress
+ onProgress = function(e:ProgressEvent):void {
+ dispatchEvent(e);
+ };
+ file._fileRef.addEventListener(ProgressEvent.PROGRESS, onProgress);
+
+ file._fileRef.upload(request, fileDataName, false);
+ }
+
+ public function advancedUpload(url:String, settings:Object):void {
+ var file:File = this, width:int, height:int, quality:int, multipart:Boolean, chunking:Boolean, fileDataName:String;
+ var chunk:int, chunks:int, chunkSize:int, postvars:Object;
+ var onComplete:Function, onIOError:Function;
+ var removeAllListeners:Function = function() : void {
+ file._fileRef.removeEventListener(Event.COMPLETE, onComplete);
+ file._fileRef.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
+ };
+
+ // Setup internal vars
+ this._uploadUrl = url;
+ this._cancelled = false;
+ this._headers = settings.headers;
+ this._mimeType = settings.mime;
+
+ // make it available for whole class (cancelUpload requires it for example)
+ this._removeAllListeners = removeAllListeners;
+
+ multipart = new Boolean(settings["multipart"]);
+ fileDataName = new String(settings["file_data_name"]);
+ chunkSize = settings["chunk_size"];
+ chunking = chunkSize > 0;
+ postvars = settings["multipart_params"];
+ chunk = 0;
+
+ // When file is loaded start uploading
+ onComplete = function(e:Event):void {
+ removeAllListeners();
+
+ var startUpload:Function = function() : void
+ {
+ if (chunking) {
+ chunks = Math.ceil(file._size / chunkSize);
+
+ // Force at least 4 chunks to fake progress. We need to fake this since the URLLoader
+ // doesn't have a upload progress event and we can't use FileReference.upload since it
+ // doesn't support cookies, breaks on HTTPS and doesn't support custom data so client
+ // side image resizing will not be possible.
+ if (chunks < 4 && file._size > 1024 * 32) {
+ chunkSize = Math.ceil(file._size / 4);
+ chunks = 4;
+ }
+ } else {
+ // If chunking is disabled then upload file in one huge chunk
+ chunkSize = file._size;
+ chunks = 1;
+ }
+
+ // Start uploading the scaled down image
+ file._multipart = multipart;
+ file._fileDataName = fileDataName;
+ file._chunking = chunking;
+ file._chunk = chunk;
+ file._chunks = chunks;
+ file._chunkSize = chunkSize;
+ file._postvars = postvars;
+
+ file.uploadNextChunk();
+ }
+
+ if (/\.(jpeg|jpg|png)$/i.test(file._fileName) && (settings["width"] || settings["height"] || settings["quality"])) {
+ var image:Image = new Image(file._fileRef.data);
+ image.addEventListener(ImageEvent.COMPLETE, function(e:ImageEvent) : void
+ {
+ image.removeAllEventListeners();
+ if (image.imageData) {
+ file._imageData = image.imageData;
+ file._imageData.position = 0;
+ file._size = image.imageData.length;
+ }
+ startUpload();
+ });
+ image.addEventListener(ImageEvent.ERROR, function(e:ImageEvent) : void
+ {
+ image.removeAllEventListeners();
+ file.dispatchEvent(e);
+ });
+ image.addEventListener(ExifParserEvent.EXIF_DATA, function(e:ExifParserEvent) : void
+ {
+ file.dispatchEvent(e);
+ });
+ image.addEventListener(ExifParserEvent.GPS_DATA, function(e:ExifParserEvent) : void
+ {
+ file.dispatchEvent(e);
+ });
+ image.scale(settings["width"], settings["height"], settings["quality"]);
+ } else {
+ startUpload();
+ }
+ };
+ this._fileRef.addEventListener(Event.COMPLETE, onComplete);
+
+ // File load IO error
+ onIOError = function(e:Event):void {
+ removeAllListeners();
+ dispatchEvent(e);
+ };
+ this._fileRef.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
+
+ // Start loading local file
+ this._fileRef.load();
+ }
+
+ /**
+ * Uploads the next chunk or terminates the upload loop if all chunks are done.
+ */
+ public function uploadNextChunk():Boolean {
+ var file:File = this, fileData:ByteArray, chunkData:ByteArray, req:URLRequest, url:String;
+ var onComplete:Function, onIOError:Function, onSecurityError:Function;
+ var removeAllEventListeners:Function = function() : void {
+ file._urlStream.removeEventListener(Event.COMPLETE, onComplete);
+ file._urlStream.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
+ file._urlStream.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
+ };
+
+ this._removeAllURLStreamListeners = removeAllEventListeners;
+
+ // All chunks uploaded?
+ if (this._chunk >= this._chunks) {
+ // Clean up memory
+ if(this._fileRef.data) {
+ this._fileRef.data.clear();
+ }
+ this._imageData = null;
+
+ return false;
+ }
+
+ // Slice out a chunk
+ chunkData = new ByteArray();
+
+ // Use image data if it exists, will exist if the image was resized
+ if (this._imageData != null)
+ fileData = this._imageData;
+ else
+ fileData = this._fileRef.data;
+
+ fileData.readBytes(chunkData, 0, fileData.position + this._chunkSize > fileData.length ? fileData.length - fileData.position : this._chunkSize);
+
+ // Setup URL stream
+ file._urlStream = null;
+ file._urlStream = new URLStream();
+
+ // Wait for response and dispatch it
+ onComplete = function(e:Event):void {
+
+
+ var response:String = file._urlStream.readUTFBytes(file._urlStream.bytesAvailable);
+
+ // Fake UPLOAD_COMPLETE_DATA event
+ var uploadChunkEvt:UploadChunkEvent = new UploadChunkEvent(
+ UploadChunkEvent.UPLOAD_CHUNK_COMPLETE_DATA,
+ false,
+ false,
+ response,
+ file._chunk,
+ file._chunks
+ );
+
+ file._chunk++;
+ dispatchEvent(uploadChunkEvt);
+
+ // Fake progress event since Flash doesn't have a progress event for streaming data up to the server
+ var pe:ProgressEvent = new ProgressEvent(ProgressEvent.PROGRESS, false, false, fileData.position, file._size);
+ dispatchEvent(pe);
+
+ // Clean up memory
+ file._urlStream.close();
+ removeAllEventListeners();
+ chunkData.clear();
+ };
+ file._urlStream.addEventListener(Event.COMPLETE, onComplete);
+
+ // Delegate upload IO errors
+ onIOError = function(e:IOErrorEvent):void {
+ removeAllEventListeners();
+ dispatchEvent(e);
+ };
+ file._urlStream.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
+
+ // Delegate secuirty errors
+ onSecurityError = function(e:SecurityErrorEvent):void {
+ removeAllEventListeners();
+ dispatchEvent(e);
+ };
+ file._urlStream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
+
+ // Setup URL
+ url = this._uploadUrl;
+
+ // Add name and chunk/chunks to URL if we use direct streaming method
+ if (!this._multipart) {
+ if (url.indexOf('?') == -1)
+ url += '?';
+ else
+ url += '&';
+
+ url += "name=" + encodeURIComponent(this._settings["name"]);
+
+ if (this._chunking) {
+ url += "&chunk=" + this._chunk + "&chunks=" + this._chunks;
+ }
+ }
+
+ // Setup request
+ req = new URLRequest(url);
+ req.method = URLRequestMethod.POST;
+
+ // Add custom headers
+ if (this._headers) {
+ for (var headerName:String in this._headers) {
+ req.requestHeaders.push(new URLRequestHeader(headerName, this._headers[headerName]));
+ }
+ }
+
+ // Build multipart request
+ if (this._multipart) {
+ var boundary:String = '----pluploadboundary' + new Date().getTime(),
+ dashdash:String = '--', crlf:String = '\r\n', multipartBlob: ByteArray = new ByteArray();
+
+ req.requestHeaders.push(new URLRequestHeader("Content-Type", 'multipart/form-data; boundary=' + boundary));
+
+ this._postvars["name"] = this._settings["name"];
+
+ // Add chunking parameters if needed
+ if (this._chunking) {
+ this._postvars["chunk"] = this._chunk;
+ this._postvars["chunks"] = this._chunks;
+ }
+
+ // Append mutlipart parameters
+ for (var name:String in this._postvars) {
+ multipartBlob.writeUTFBytes(
+ dashdash + boundary + crlf +
+ 'Content-Disposition: form-data; name="' + name + '"' + crlf + crlf +
+ this._postvars[name] + crlf
+ );
+ }
+
+ // Add file header
+ multipartBlob.writeUTFBytes(
+ dashdash + boundary + crlf +
+ 'Content-Disposition: form-data; name="' + this._fileDataName + '"; filename="' + this._fileName + '"' + crlf +
+ 'Content-Type: ' + this._mimeType + crlf + crlf
+ );
+
+ // Add file data
+ multipartBlob.writeBytes(chunkData, 0, chunkData.length);
+
+ // Add file footer
+ multipartBlob.writeUTFBytes(crlf + dashdash + boundary + dashdash + crlf);
+ req.data = multipartBlob;
+ } else {
+ req.requestHeaders.push(new URLRequestHeader("Content-Type", "application/octet-stream"));
+ req.data = chunkData;
+ }
+
+ // Make request
+ setTimeout(function() : void { // otherwise URLStream eventually hangs for Chrome+Flash (as of FP11.2 r202)
+ file._urlStream.load(req);
+ }, 1);
+ return true;
+ }
+ }
+}
diff --git a/debian/missing-sources/plupload/flash/plupload/src/com/plupload/Plupload.as b/debian/missing-sources/plupload/flash/plupload/src/com/plupload/Plupload.as
new file mode 100644
index 0000000..2c4981f
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/src/com/plupload/Plupload.as
@@ -0,0 +1,413 @@
+/**
+ * Plupload.as
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+package com.plupload {
+ import flash.display.LoaderInfo;
+ import flash.display.Sprite;
+ import flash.errors.IOError;
+ import flash.net.FileReferenceList;
+ import flash.net.FileReference;
+ import flash.net.FileFilter;
+ import flash.net.URLLoader;
+ import flash.net.URLRequest;
+ import flash.net.URLRequestMethod;
+ import flash.net.URLVariables;
+ import flash.net.URLStream;
+ import flash.events.Event;
+ import flash.events.MouseEvent;
+ import flash.events.FocusEvent;
+ import flash.events.ProgressEvent;
+ import flash.events.IOErrorEvent;
+ import flash.events.SecurityErrorEvent;
+ import flash.events.DataEvent;
+ import flash.display.MovieClip;
+ import flash.display.StageAlign;
+ import flash.display.StageScaleMode;
+ import flash.external.ExternalInterface;
+ import flash.utils.ByteArray;
+ import flash.utils.Dictionary;
+ import flash.errors.IllegalOperationError;
+ import flash.system.Security;
+ import com.mxi.image.events.ImageEvent;
+ import com.mxi.image.events.ExifParserEvent;
+
+ /**
+ * This is the main class of the Plupload package.
+ */
+ public class Plupload extends Sprite {
+ // Private fields
+ private var clickArea:MovieClip;
+ private var fileRefList:FileReferenceList;
+ private var files:Dictionary;
+ private var idCounter:int = 0;
+ private var currentFile:File;
+ private var id:String;
+ private var fileFilters:Array;
+ private var multipleFiles:Boolean;
+ private var fileRefArray:Array = [];
+ private var fileRef:FileReference;
+ private var _disabled:Boolean = false;
+
+ /**
+ * Main constructor for the Plupload class.
+ */
+ public function Plupload():void {
+ if (stage)
+ init();
+ else
+ addEventListener(Event.ADDED_TO_STAGE, init);
+ }
+
+ /**
+ * Initialization event handler.
+ *
+ * @param e Event object.
+ */
+ private function init(e:Event = null):void {
+ removeEventListener(Event.ADDED_TO_STAGE, init);
+
+ // Allow cross domain scripting access
+ // Security.allowDomain("*");
+
+ // Setup id
+ this.id = (this.stage.loaderInfo.parameters["id"]).toString().replace(/[^\w]/g, ''); // allow only [a-zA-Z0-9_]
+
+ // Setup file reference list
+ this.fileRefList = new FileReferenceList();
+ this.fileRefList.addEventListener(Event.CANCEL, cancelEvent);
+ this.fileRefList.addEventListener(Event.SELECT, selectEvent);
+
+ initSingleFileReference();
+
+ this.files = new Dictionary();
+
+ // Align and scale stage
+ this.stage.align = StageAlign.TOP_LEFT;
+ this.stage.scaleMode = StageScaleMode.NO_SCALE;
+
+ // Add something to click on
+ this.clickArea = new MovieClip();
+ this.clickArea.graphics.beginFill(0x000000, 0); // Fill with transparent color
+ this.clickArea.graphics.drawRect(0, 0, 1024, 1024);
+ this.clickArea.x = 0;
+ this.clickArea.y = 0;
+ this.clickArea.width = 1024;
+ this.clickArea.height = 1024;
+ this.clickArea.graphics.endFill();
+ this.clickArea.buttonMode = true;
+ this.clickArea.useHandCursor = true;
+ addChild(this.clickArea);
+
+ // Register event handlers
+ this.clickArea.addEventListener(MouseEvent.ROLL_OVER, this.stageEvent);
+ this.clickArea.addEventListener(MouseEvent.ROLL_OUT, this.stageEvent);
+ this.clickArea.addEventListener(MouseEvent.CLICK, this.stageClickEvent);
+ this.clickArea.addEventListener(MouseEvent.MOUSE_DOWN, this.stageEvent);
+ this.clickArea.addEventListener(MouseEvent.MOUSE_UP, this.stageEvent);
+ this.clickArea.addEventListener(FocusEvent.FOCUS_IN, this.stageEvent);
+ this.clickArea.addEventListener(FocusEvent.FOCUS_OUT, this.stageEvent);
+
+ // Add external callbacks
+ ExternalInterface.addCallback('disableBrowse', this.disableBrowse);
+ ExternalInterface.addCallback('uploadFile', this.uploadFile);
+ ExternalInterface.addCallback('removeFile', this.removeFile);
+ ExternalInterface.addCallback('cancelUpload', this.cancelUpload);
+ ExternalInterface.addCallback('clearQueue', this.clearFiles);
+ ExternalInterface.addCallback('setFileFilters', this.setFileFilters);
+ ExternalInterface.addCallback('uploadNextChunk', this.uploadNextChunk);
+
+ this.fireEvent("Init");
+ }
+
+
+ /**
+ * In case of multipleFiles=false FileReference needs to be reinitialized for every file select dialog
+ */
+ private function initSingleFileReference() : void {
+ if (this.fileRef) {
+ this.fileRef = null;
+ }
+
+ this.fileRef = new FileReference();
+ this.fileRef.addEventListener(Event.CANCEL, cancelEvent);
+ this.fileRef.addEventListener(Event.SELECT, selectEvent);
+ }
+
+ /**
+ * Event handler for selection cancelled. This simply fires the event out to the page level JS.
+ *
+ * @param e Event object.
+ */
+ private function cancelEvent(e:Event):void {
+ this.fireEvent("CancelSelect");
+ }
+
+ /**
+ * Event handler for when the user select files to upload. This method builds up a simpler object
+ * representation and passes this back to the page level JS.
+ *
+ * @param e Event object.
+ */
+ private function selectEvent(e:Event):void {
+ var selectedFiles:Array = [], files:Dictionary = this.files;
+
+ function processFile(file:File):void {
+ // Add progress listener
+ file.addEventListener(ProgressEvent.PROGRESS, function(e:ProgressEvent):void {
+ var file:File = e.target as File;
+
+ fireEvent("UploadProcess", {
+ id : file.id,
+ loaded : e.bytesLoaded,
+ size : e.bytesTotal
+ });
+ });
+
+ // Add error listener
+ file.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent):void {
+ var file:File = e.target as File;
+
+ fireEvent("IOError", {
+ id : file.id,
+ message : e.text.replace(/\\/g, "\\\\")
+ });
+ });
+
+ // Add error listener
+ file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function(e:SecurityErrorEvent):void {
+ var file:File = e.target as File;
+
+ fireEvent("SecurityError", {
+ id : file.id,
+ message : e.text.replace(/\\/g, "\\\\")
+ });
+ });
+
+ file.addEventListener(ExifParserEvent.EXIF_DATA, function(e:ExifParserEvent) : void {
+ var file:File = e.target as File;
+
+ fireEvent("ExifData", {
+ id : file.id,
+ data : e.data
+ });
+ });
+
+
+ file.addEventListener(ExifParserEvent.GPS_DATA, function(e:ExifParserEvent) : void
+ {
+ var file:File = e.target as File;
+
+ fireEvent("GpsData", {
+ id : file.id,
+ data : e.data
+ });
+ });
+
+
+ file.addEventListener(ImageEvent.ERROR, function(e:ImageEvent) : void {
+ var file:File = e.target as File;
+
+ fireEvent("ImageError", {
+ id : file.id,
+ code: e.code
+ });
+ });
+
+
+ // Add response listener
+ file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, function(e:DataEvent):void {
+ var file:File = e.target as File;
+
+ fireEvent("UploadComplete", {
+ id : file.id,
+ text : e.text.replace(/\\/g, "\\\\")
+ });
+ });
+
+ // Add chunk response listener
+ file.addEventListener(UploadChunkEvent.UPLOAD_CHUNK_COMPLETE_DATA, function(e:UploadChunkEvent):void {
+ var file:File = e.target as File;
+
+ fireEvent("UploadChunkComplete", {
+ id : file.id,
+ text : e.text.replace(/\\/g, "\\\\"),
+ chunk : e.chunk,
+ chunks : e.chunks
+ });
+ });
+
+ files[file.id] = file;
+
+ // Setup selected files object to pass page to page level js
+ selectedFiles.push({id : file.id, name : file.fileName, size : file.size, loaded : 0});
+ }
+
+ if (this.multipleFiles) {
+ for (var i:Number = 0; i < this.fileRefList.fileList.length; i++) {
+ processFile(new File("file_" + (this.idCounter++), this.fileRefList.fileList[i]));
+ }
+ } else {
+ processFile(new File("file_" + (this.idCounter++), this.fileRef));
+ this.fileRefArray.push(this.fileRef);
+ initSingleFileReference();
+ }
+
+ this.fireEvent("SelectFiles", selectedFiles);
+ }
+
+ /**
+ * Sefnd out all stage events to page level JS inorder to fake click, hover etc.
+ *
+ * @param e Event object.
+ */
+ private function stageEvent(e:Event):void {
+ this.fireEvent("StageEvent:" + e.type);
+ }
+
+ /**
+ * Event handler that get executed when the user clicks the state. This will bring up
+ * the file browser dialog.
+ *
+ * @param e Event object.
+ */
+ private function stageClickEvent(e:Event):void {
+ var filters:Array = [], i:int;
+
+ if (this._disabled) {
+ return;
+ }
+
+ if (this.fileFilters != null) {
+ for (i = 0; i < this.fileFilters.length; i++) {
+ filters.push(new FileFilter(
+ this.fileFilters[i].title,
+ '*.' + this.fileFilters[i].extensions.replace(/,/g, ";*."),
+ this.fileFilters[i].mac_types
+ ));
+ }
+ }
+
+ try {
+ if (this.multipleFiles) {
+ if (filters.length > 0)
+ this.fileRefList.browse(filters);
+ else
+ this.fileRefList.browse();
+ } else {
+ if (filters.length > 0)
+ this.fileRef.browse(filters);
+ else
+ this.fileRef.browse();
+ }
+ } catch (ex1:IllegalOperationError) {
+ this.fireEvent("SelectError", ex1.message);
+ } catch (ex2:ArgumentError) {
+ this.fireEvent("SelectError", ex2.message);
+ }
+ }
+
+ /**
+ * Disable file dialog trigger.
+ *
+ * @param disabled Boolean Disable or enable file dialog trigger.
+ */
+ private function disableBrowse(disabled:Boolean = true):void {
+ this._disabled = disabled;
+ }
+
+
+ /**
+ * External interface function. This can be called from page level JS to start the upload of a specific file.
+ *
+ * @param id File id to upload.
+ * @param url Url to upload the file to.
+ * @param settings Settings object.
+ */
+ private function uploadFile(id:String, url:String, settings:Object):void {
+ var file:File = this.files[id] as File;
+
+ if (file) {
+ this.currentFile = file;
+ file.upload(url, settings);
+ }
+ }
+
+ /**
+ * Uploads the next chunk of the current file will return false when all chunks are uploaded.
+ *
+ * @return true/false if there is chunks left to upload.
+ */
+ private function uploadNextChunk():Boolean {
+ if (this.currentFile) {
+ return this.currentFile.uploadNextChunk();
+ }
+
+ return false;
+ }
+
+ /**
+ * File id to remove form upload queue.
+ *
+ * @param id Id of the file to remove.
+ */
+ private function removeFile(id:String):void {
+ if (this.files[id] != null)
+ delete this.files[id];
+ }
+
+ /**
+ * Cancel upload.
+ */
+ private function cancelUpload(): void {
+ if (this.currentFile) {
+ this.currentFile.cancelUpload();
+ }
+ }
+
+ /**
+ * Remove all files from upload queue.
+ *
+ * @param id Id of the file to remove.
+ */
+ private function clearFiles():void {
+ this.files = new Dictionary();
+ }
+
+ /**
+ * Sets file filters to be used for selection.
+ *
+ * @param filters Id of the file to remove.
+ * @param multi Bool state if multiple files is to be selected.
+ */
+ private function setFileFilters(filters:Array, multi:Boolean):void {
+ this.fileFilters = filters;
+ this.multipleFiles = multi;
+ }
+
+ /**
+ * Fires an event from the flash movie out to the page level JS.
+ *
+ * @param type Name of event to fire.
+ * @param obj Object with optional data.
+ */
+ private function fireEvent(type:String, obj:Object = null):void {
+ ExternalInterface.call("plupload.flash.trigger", this.id, type, obj);
+ }
+
+ /**
+ * Debugs out a message to Firebug.
+ *
+ * @param msg Message to output to firebug.
+ */
+ public static function debug(msg:String):void {
+ ExternalInterface.call("console.log", msg);
+ }
+ }
+}
diff --git a/debian/missing-sources/plupload/flash/plupload/src/com/plupload/UploadChunkEvent.as b/debian/missing-sources/plupload/flash/plupload/src/com/plupload/UploadChunkEvent.as
new file mode 100644
index 0000000..1b3d6a3
--- /dev/null
+++ b/debian/missing-sources/plupload/flash/plupload/src/com/plupload/UploadChunkEvent.as
@@ -0,0 +1,56 @@
+/**
+ * UploadChunkEvent.as
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+package com.plupload {
+ import flash.events.DataEvent;
+
+ /**
+ * This class is used for uploads of chunks.
+ */
+ public class UploadChunkEvent extends DataEvent {
+ // Private fields
+ private var _chunk:int, _chunks:int;
+
+ /**
+ * Chunk complete event name.
+ */
+ public static const UPLOAD_CHUNK_COMPLETE_DATA:String = 'uploadchunk';
+
+ /**
+ * Chunk property.
+ */
+ public function get chunk():int {
+ return this._chunk;
+ }
+
+ /**
+ * Chunks property.
+ */
+ public function get chunks():int {
+ return this._chunks;
+ }
+
+ /**
+ * Main constructor for the UploadChunkEvent.
+ *
+ * @param type
+ * @param bubbles
+ * @param cancelable
+ * @param data
+ * @param chunk
+ * @param chunks
+ */
+ function UploadChunkEvent(type:String, bubbles:Boolean, cancelable:Boolean, data:String, chunk:int, chunks:int) {
+ super(type, bubbles, cancelable, data);
+ this._chunk = chunk;
+ this._chunks = chunks;
+ }
+ }
+} \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/cs.js b/debian/missing-sources/plupload/javascript/i18n/cs.js
new file mode 100644
index 0000000..1ee5d5f
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/cs.js
@@ -0,0 +1,14 @@
+// .po file like language pack
+plupload.addI18n({
+ 'Select files' : 'Vyberte soubory',
+ 'Add files to the upload queue and click the start button.' : 'Přidejte soubory do fronty a pak spusťte nahrávání.',
+ 'Filename' : 'Název souboru',
+ 'Status' : 'Status',
+ 'Size' : 'Velikost',
+ 'Add Files' : 'Přidat soubory',
+ 'Stop current upload' : 'Zastavit nahrávání',
+ 'Start uploading queue' : 'Spustit frontu nahrávání',
+ 'Drag files here.' : 'Sem přetáhněte soubory.',
+ 'Start Upload': 'Spustit nahrávání',
+ 'Uploaded %d/%d files': 'Nahráno %d/%d souborů'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/da.js b/debian/missing-sources/plupload/javascript/i18n/da.js
new file mode 100644
index 0000000..fc95896
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/da.js
@@ -0,0 +1,12 @@
+// .po file like language pack
+plupload.addI18n({
+ 'Select files' : 'Vælg filer',
+ 'Add files to the upload queue and click the start button.' : 'Tilføj filer til køen, og tryk på start.',
+ 'Filename' : 'Filnavn',
+ 'Status' : 'Status',
+ 'Size' : 'Størrelse',
+ 'Add files' : 'Tilføj filer',
+ 'Stop current upload' : 'Stop upload',
+ 'Start uploading queue' : 'Start upload',
+ 'Drag files here.' : 'Træk filer her.'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/de.js b/debian/missing-sources/plupload/javascript/i18n/de.js
new file mode 100644
index 0000000..4c4de07
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/de.js
@@ -0,0 +1,24 @@
+// German
+plupload.addI18n({
+ 'Select files' : 'Dateien hochladen',
+ 'Add files to the upload queue and click the start button.' : 'Dateien hinzuf&uuml;gen und auf \'Hochladen\' klicken.',
+ 'Filename' : 'Dateiname',
+ 'Status' : 'Status',
+ 'Size' : 'Gr&ouml;&szlig;e',
+ 'Add files' : 'Dateien', // hinzuf&uuml;gen',
+ 'Stop current upload' : 'Aktuelles Hochladen stoppen',
+ 'Start uploading queue' : 'Hochladen starten',
+ 'Uploaded %d/%d files': '%d/%d Dateien sind hochgeladen',
+ 'N/A' : 'Nicht verf&uuml;gbar',
+ 'Drag files here.' : 'Ziehen Sie die Dateien hier hin',
+ 'File extension error.': 'Fehler bei Dateiendung',
+ 'File size error.': 'Fehler bei Dateigr&ouml;ße',
+ 'Init error.': 'Initialisierungsfehler',
+ 'HTTP Error.': 'HTTP-Fehler',
+ 'Security error.': 'Sicherheitsfehler',
+ 'Generic error.': 'Typischer Fehler',
+ 'IO error.': 'Ein/Ausgabe-Fehler',
+ 'Stop Upload': 'Hochladen stoppen',
+ 'Start upload': 'Hochladen',
+ '%d files queued': '%d Dateien in der Warteschlange'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/el.js b/debian/missing-sources/plupload/javascript/i18n/el.js
new file mode 100644
index 0000000..aafbaf1
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/el.js
@@ -0,0 +1,14 @@
+// Greek
+plupload.addI18n({
+ 'Select files' : 'Επιλέξτε ΑÏχεία',
+ 'Add files to the upload queue and click the start button.' : 'ΠÏοσθήκη αÏχείων στην ουÏά μεταφόÏτωσης',
+ 'Filename' : 'Όνομα αÏχείου',
+ 'Status' : 'Κατάσταση',
+ 'Size' : 'Μέγεθος',
+ 'Add Files' : 'ΠÏοσθέστε αÏχεία',
+ 'Stop current upload' : 'Διακοπή Ï„Ïέχουσας μεταφόÏτωσης',
+ 'Start uploading queue' : 'Εκκίνηση μεταφόÏτωσης ουÏάς αÏχείων',
+ 'Drag files here.' : 'ΣÏÏετε αÏχεία εδώ',
+ 'Start Upload': 'Εκκίνηση μεταφόÏτωσης',
+ 'Uploaded %d/%d files': 'Ανέβηκαν %d/%d αÏχεία'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/es.js b/debian/missing-sources/plupload/javascript/i18n/es.js
new file mode 100644
index 0000000..2379421
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/es.js
@@ -0,0 +1,25 @@
+// Spanish
+plupload.addI18n({
+ 'Select files' : 'Elija archivos:',
+ 'Add files to the upload queue and click the start button.' : 'Agregue archivos a la cola de subida y haga click en el boton de iniciar.',
+ 'Filename' : 'Nombre de archivo',
+ 'Status' : 'Estado',
+ 'Size' : 'Tama&ntilde;o',
+ 'Add files' : 'Agregue archivos',
+ 'Stop current upload' : 'Detener subida actual',
+ 'Start uploading queue' : 'Iniciar subida de cola',
+ 'Uploaded %d/%d files': 'Subidos %d/%d archivos',
+ 'N/A' : 'No disponible',
+ 'Drag files here.' : 'Arrastre archivos aqu&iacute;',
+ 'File extension error.': 'Error de extensi&oacute;n de archivo.',
+ 'File size error.': 'Error de tama&ntilde;o de archivo.',
+ 'Init error.': 'Error de inicializaci&oacute;n.',
+ 'HTTP Error.': 'Error de HTTP.',
+ 'Security error.': 'Error de seguridad.',
+ 'Generic error.': 'Error gen&eacute;rico.',
+ 'IO error.': 'Error de entrada/salida.',
+ 'Stop Upload': 'Detener Subida.',
+ 'Add Files': 'Agregar Archivos',
+ 'Start Upload': 'Comenzar Subida.',
+ '%d files queued': '%d archivos en cola.'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/et.js b/debian/missing-sources/plupload/javascript/i18n/et.js
new file mode 100644
index 0000000..a4a5e3a
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/et.js
@@ -0,0 +1,33 @@
+// Estonian translation, et.js
+plupload.addI18n({
+ 'Select files' : 'Vali faile',
+ 'Add files to the upload queue and click the start button.' : 'Lisa failid üleslaadimise järjekorda ja klõpsa alustamise nupule.',
+ 'Filename' : 'Failinimi',
+ 'Status' : 'Olek',
+ 'Size' : 'Suurus',
+ 'Add files' : 'Lisa faile',
+ 'Stop current upload' : 'Praeguse üleslaadimise peatamine',
+ 'Start uploading queue' : 'Järjekorras ootavate failide üleslaadimise alustamine',
+ 'Drag files here.' : 'Lohista failid siia.',
+ 'Start upload' : 'Alusta üleslaadimist',
+ 'Uploaded %d/%d files': 'Ãœles laaditud %d/%d',
+ 'Stop upload': 'Peata üleslaadimine',
+ 'Start upload': 'Alusta üleslaadimist',
+ '%d files queued': 'Järjekorras on %d faili',
+ 'File: %s': 'Fail: %s',
+ 'Close': 'Sulge',
+ 'Using runtime: ': 'Kasutatakse varianti: ',
+ 'File: %f, size: %s, max file size: %m': 'Fail: %f, suurus: %s, suurim failisuurus: %m',
+ 'Upload element accepts only %d file(s) at a time. Extra files were stripped.': 'Üleslaadimise element saab vastu võtta ainult %d faili ühe korraga. Ülejäänud failid jäetakse laadimata.',
+ 'Upload URL might be wrong or doesn\'t exist': 'Üleslaadimise URL võib olla vale või seda pole',
+ 'Error: File too large: ': 'Viga: fail on liiga suur: ',
+ 'Error: Invalid file extension: ': 'Viga: sobimatu faililaiend: ',
+ 'File extension error.': 'Faililaiendi viga.',
+ 'File size error.': 'Failisuuruse viga.',
+ 'File count error.': 'Failide arvu viga.',
+ 'Init error.': 'Lähtestamise viga.',
+ 'HTTP Error.': 'HTTP ühenduse viga.',
+ 'Security error.': 'Turvaviga.',
+ 'Generic error.': 'Ãœldine viga.',
+ 'IO error.': 'S/V (I/O) viga.'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/fa.js b/debian/missing-sources/plupload/javascript/i18n/fa.js
new file mode 100644
index 0000000..af36e22
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/fa.js
@@ -0,0 +1,37 @@
+// Persian
+plupload.addI18n({
+ 'Select files' : 'انتخاب Ùایل',
+ 'Add files to the upload queue and click the start button.' : 'اضاÙÙ‡ کنید Ùایل ها را به ص٠آپلود Ùˆ دکمه شروع را کلیک کنید.',
+ 'Filename' : 'نام Ùایل',
+ 'Status' : 'وضعیت',
+ 'Size' : 'سایز',
+ 'Add Files' : 'اÙزودن Ùایل',
+ 'Stop Upload' : 'توق٠انتقال',
+ 'Start Upload' : 'شروع انتقال',
+ 'Add files' : 'اÙزودن Ùایل',
+ 'Add files.' : 'اÙزودن Ùایل',
+ 'Stop current upload' : 'توق٠انتقال جاری',
+ 'Start uploading queue' : 'شروع ص٠انتقال',
+ 'Stop upload' : 'توق٠انتقال',
+ 'Start upload' : 'شروع انتقال',
+ 'Uploaded %d/%d files': 'منتقل شد %d/%d از Ùایلها',
+ 'N/A' : 'N/A',
+ 'Drag files here.' : 'بکشید Ùایل ها رو به اینجا',
+ 'File extension error.': 'خطا پیشوند Ùایل',
+ 'File size error.': 'خطای سایز Ùایل',
+ 'File count error.': 'خطای تعداد Ùایل',
+ 'Init error.': 'خطا در استارت اسکریپت',
+ 'HTTP Error.': 'HTTP خطای',
+ 'Security error.': 'خطای امنیتی',
+ 'Generic error.': 'خطای عمومی',
+ 'IO error.': 'IO خطای',
+ 'File: %s': ' Ùایل ها : %s',
+ 'Close': 'بستن',
+ '%d files queued': '%d Ùایل در صÙ',
+ 'Using runtime: ': 'استÙاده میکنید از : ',
+ 'File: %f, size: %s, max file size: %m': Ùایل: %f, سایز: %s, بزرگترین سایز Ùایل: %m',
+ 'Upload element accepts only %d file(s) at a time. Extra files were stripped.': 'عنصر بارگذار Ùقط %d Ùایل رو در یک زمان Ù…ÛŒ پذیرد. سایر Ùایل ها مجرد از این موضوع هستند.',
+ 'Upload URL might be wrong or doesn\'t exist': 'آدرس آپلود اشتباه می باشد یا وجود ندارد',
+ 'Error: File too large: ': 'خطا: Ùایل حجیم است :: ',
+ 'Error: Invalid file extension: ': 'خطا پسوند Ùایل معتبر نمی باشد : '
+});
diff --git a/debian/missing-sources/plupload/javascript/i18n/fi.js b/debian/missing-sources/plupload/javascript/i18n/fi.js
new file mode 100644
index 0000000..12a639e
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/fi.js
@@ -0,0 +1,33 @@
+// .fi file like language pack
+plupload.addI18n({
+ 'Select files' : 'Valitse tiedostoja',
+ 'Add files to the upload queue and click the start button.' : 'Lisää tiedostoja latausjonoon ja klikkaa aloita-nappia.',
+ 'Filename' : 'Tiedostonimi',
+ 'Status' : 'Tila',
+ 'Size' : 'Koko',
+ 'Add files' : 'Lisää tiedostoja',
+ 'Stop current upload' : 'Pysäytä nykyinen lataus',
+ 'Start uploading queue' : 'Aloita jonon lataus',
+ 'Drag files here.' : 'Raahaa tiedostot tänne.',
+ 'Start upload' : 'Aloita lataus',
+ 'Uploaded %d/%d files': 'Ladattu %d/%d tiedostoa',
+ 'Stop upload': 'Pysäytä lataus',
+ 'Start upload': 'Aloita lataus',
+ '%d files queued': '%d tiedostoa jonossa',
+ 'File: %s': 'Tiedosto: %s',
+ 'Close': 'Sulje',
+ 'Using runtime: ': 'Käytetään ajonaikaista: ',
+ 'File: %f, size: %s, max file size: %m': 'Tiedosto: %f, koko: %s, maksimi tiedostokoko: %m',
+ 'Upload element accepts only %d file(s) at a time. Extra files were stripped.': 'Latauselementti sallii ladata vain %d tiedosto(a) kerrallaan. Ylimääräiset tiedostot ohitettiin.',
+ 'Upload URL might be wrong or doesn\'t exist': 'Lataus URL saattaa olla väärin tai ei ole olemassa',
+ 'Error: File too large: ': 'Virhe: Tiedosto liian suuri: ',
+ 'Error: Invalid file extension: ': 'Virhe: Kelpaamaton tiedostopääte: ',
+ 'File extension error.': 'Tiedostopäätevirhe.',
+ 'File size error.': 'Tiedostokokovirhe.',
+ 'File count error.': 'Tiedostolaskentavirhe.',
+ 'Init error.': 'Init virhe.',
+ 'HTTP Error.': 'HTTP virhe.',
+ 'Security error.': 'Tietoturvavirhe.',
+ 'Generic error.': 'Yleinen virhe.',
+ 'IO error.': 'I/O virhe.'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/fr-ca.js b/debian/missing-sources/plupload/javascript/i18n/fr-ca.js
new file mode 100644
index 0000000..61aba23
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/fr-ca.js
@@ -0,0 +1,35 @@
+// French-Canadian
+plupload.addI18n({
+ 'Select files' : 'Sélectionnez les fichiers',
+ 'Add files to the upload queue and click the start button.' : 'Ajoutez des fichiers à la file d\'attente et appuyez sur le bouton démarrer.',
+ 'Filename' : 'Nom du fichier',
+ 'Status' : 'Statut',
+ 'Size' : 'Taille',
+ 'Add files' : 'Ajouter Fichiers',
+ 'Stop current upload' : 'Arrêter le téléversement actuel',
+ 'Start uploading queue' : 'Démarrer le téléversement',
+ 'Uploaded %d/%d files': '%d/%d fichiers envoyés',
+ 'N/A' : 'Non applicable',
+ 'Drag files here.' : 'Glisser-déposer les fichiers ici',
+ 'File extension error.': 'Erreur d\'extension de fichier',
+ 'File size error.': 'Erreur de taille de fichier',
+ 'Init error.': 'Erreur d\'initialisation',
+ 'HTTP Error.': 'Erreur HTTP',
+ 'Security error.': 'Erreur de sécurité',
+ 'Generic error.': 'Erreur commune',
+ 'IO error.': 'Erreur E/S',
+ 'Stop Upload': 'Arrêter le téléversement',
+ 'Add Files': 'Ajouter des fichiers',
+ 'Start upload': 'Démarrer le téléversement',
+ '%d files queued': '%d fichiers en attente',
+ 'File: %s':'Fichier: %s',
+ 'Close':'Fermer',
+ 'Using runtime:':'Moteur logiciel:',
+ 'File: %f, size: %s, max file size: %m':'Fichier: %f, poids: %s, poids maximal: %m',
+ 'Upload element accepts only %d file(s) at a time. Extra files were stripped.':'La file accepte %d fichier(s) à la fois. Les fichiers en trop sont ignorés',
+ 'Upload URL might be wrong or doesn\'t exist':'L\'URL de téléversement est erroné ou inexistant',
+ 'Error: File to large: ':'Fichier trop volumineux: ',
+ 'Error: Invalid file extension: ':'Extension de fichier invalide: ',
+ 'File size error.':'Erreur de taile de fichier',
+ 'File count error.':'Erreur de décompte des fichiers'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/fr.js b/debian/missing-sources/plupload/javascript/i18n/fr.js
new file mode 100644
index 0000000..53dbe28
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/fr.js
@@ -0,0 +1,25 @@
+// French
+plupload.addI18n({
+ 'Select files' : 'Sélectionnez les fichiers',
+ 'Add files to the upload queue and click the start button.' : 'Ajoutez des fichiers à la file et appuyez sur le bouton démarrer.',
+ 'Filename' : 'Nom de fichier',
+ 'Status' : 'Status',
+ 'Size' : 'Taille',
+ 'Add files' : 'Ajouter Fichiers',
+ 'Stop current upload' : 'Arrêter l\'envoi en cours',
+ 'Start uploading queue' : 'Démarrer l\'envoi',
+ 'Uploaded %d/%d files': '%d/%d fichiers envoyés',
+ 'N/A' : 'Non applicable',
+ 'Drag files here.' : 'Déposer les fichiers ici.',
+ 'File extension error.': 'Erreur extension fichier',
+ 'File size error.': 'Erreur taille fichier.',
+ 'Init error.': 'Erreur d\'initialisation.',
+ 'HTTP Error.': 'Erreur HTTP.',
+ 'Security error.': 'Erreur de sécurité.',
+ 'Generic error.': 'Erreur générique.',
+ 'IO error.': 'Erreur E/S.',
+ 'Stop Upload': 'Arrêter les envois.',
+ 'Add Files': 'Ajouter des fichiers',
+ 'Start Upload': 'Démarrer les envois.',
+ '%d files queued': '%d fichiers en attente.'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/hr.js b/debian/missing-sources/plupload/javascript/i18n/hr.js
new file mode 100644
index 0000000..084be51
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/hr.js
@@ -0,0 +1,25 @@
+// Croatian
+plupload.addI18n({
+ 'Select files': 'Izaberite datoteke:',
+ 'Add files to the upload queue and click the start button.': 'Dodajte datoteke u listu i kliknite Upload.',
+ 'Filename': 'Ime datoteke',
+ 'Status': 'Status',
+ 'Size': 'VeliÄina',
+ 'Add files': 'Dodajte datoteke',
+ 'Stop current upload': 'Zaustavi trenutan upload',
+ 'Start uploading queue': 'Pokreni Upload',
+ 'Uploaded %d/%d files': 'Uploadano %d/%d datoteka',
+ 'N/A': 'N/A',
+ 'Drag files here.': 'Dovucite datoteke ovdje',
+ 'File extension error.': 'Greška ekstenzije datoteke.',
+ 'File size error.': 'GreÅ¡ka veliÄine datoteke.',
+ 'Init error.': 'Greška inicijalizacije.',
+ 'HTTP Error.': 'HTTP greška.',
+ 'Security error.': 'Sigurnosna greška.',
+ 'Generic error.': 'GeneriÄka greÅ¡ka.',
+ 'IO error.': 'I/O greška.',
+ 'Stop Upload': 'Zaustavi upload.',
+ 'Add Files': 'Dodaj datoteke',
+ 'Start Upload': 'Pokreni upload.',
+ '%d files queued': '%d datoteka na Äekanju.'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/hu.js b/debian/missing-sources/plupload/javascript/i18n/hu.js
new file mode 100644
index 0000000..87070ba
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/hu.js
@@ -0,0 +1,33 @@
+// Hungarian
+plupload.addI18n({
+ 'Select files' : 'Fájlok kiválasztása',
+ 'Add files to the upload queue and click the start button.' : 'Válaszd ki a fájlokat, majd kattints az Indítás gombra.',
+ 'Filename' : 'Fájlnév',
+ 'Status' : 'Ãllapot',
+ 'Size' : 'Méret',
+ 'Add files' : 'Hozzáadás',
+ 'Stop current upload' : 'Jelenlegi feltöltés megszakítása',
+ 'Start uploading queue' : 'Várakozási sor feltöltésének indítása',
+ 'Uploaded %d/%d files': 'Feltöltött fájlok: %d/%d',
+ 'N/A': 'Nem elérhető',
+ 'Drag files here.' : 'Húzd ide a fájlokat.',
+ 'Stop upload': 'Feltöltés megszakítása',
+ 'Start upload': 'Indítás',
+ '%d files queued': '%d fájl sorbaállítva',
+ 'File: %s': 'Fájl: %s',
+ 'Close': 'Bezárás',
+ 'Using runtime: ': 'Használt runtime: ',
+ 'File: %f, size: %s, max file size: %m': 'Fájl: %f, méret: %s, maximális fájlméret: %m',
+ 'Upload element accepts only %d file(s) at a time. Extra files were stripped.': 'A feltöltés egyszerre csak %d fájlt fogad el, a többi fájl nem lesz feltöltve.',
+ 'Upload URL might be wrong or doesn\'t exist': 'A megadott URL hibás vagy nem létezik',
+ 'Error: File too large: ': 'Hiba: A fájl túl nagy: ',
+ 'Error: Invalid file extension: ': 'Hiba: Érvénytelen fájlkiterjesztés: ',
+ 'File extension error.': 'Hibás fájlkiterjesztés.',
+ 'File size error.': 'Hibás fájlméret.',
+ 'File count error.': 'A fájlok számával kapcsolatos hiba.',
+ 'Init error.': 'Init hiba.',
+ 'HTTP Error.': 'HTTP hiba.',
+ 'Security error.': 'Biztonsági hiba.',
+ 'Generic error.': 'Ãltalános hiba.',
+ 'IO error.': 'I/O hiba.'
+});
diff --git a/debian/missing-sources/plupload/javascript/i18n/it.js b/debian/missing-sources/plupload/javascript/i18n/it.js
new file mode 100644
index 0000000..891e4fb
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/it.js
@@ -0,0 +1,24 @@
+// Italian
+plupload.addI18n({
+ 'Select files' : 'Seleziona i files',
+ 'Add files to the upload queue and click the start button.' : 'Aggiungi i file alla coda di caricamento e clicca il pulsante di avvio.',
+ 'Filename' : 'Nome file',
+ 'Status' : 'Stato',
+ 'Size' : 'Dimensione',
+ 'Add Files' : 'Aggiungi file',
+ 'Stop current upload' : 'Interrompi il caricamento',
+ 'Start uploading queue' : 'Avvia il caricamento',
+ 'Uploaded %d/%d files': 'Caricati %d/%d file',
+ 'N/A' : 'N/D',
+ 'Drag files here.' : 'Trascina i file qui.',
+ 'File extension error.': 'Errore estensione file.',
+ 'File size error.': 'Errore dimensione file.',
+ 'Init error.': 'Errore inizializzazione.',
+ 'HTTP Error.': 'Errore HTTP.',
+ 'Security error.': 'Errore sicurezza.',
+ 'Generic error.': 'Errore generico.',
+ 'IO error.': 'Errore IO.',
+ 'Stop Upload': 'Ferma Upload',
+ 'Start Upload': 'Inizia Upload',
+ '%d files queued': '%d file in lista'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/ja.js b/debian/missing-sources/plupload/javascript/i18n/ja.js
new file mode 100644
index 0000000..02c85ae
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/ja.js
@@ -0,0 +1,37 @@
+// Japanese
+plupload.addI18n({
+ 'Select files' : 'ファイルé¸æŠž',
+ 'Add files to the upload queue and click the start button.' : 'ファイルをアップロードキューã«è¿½åŠ ã—ã¦ã‚¹ã‚¿ãƒ¼ãƒˆãƒœã‚¿ãƒ³ã‚’クリックã—ã¦ãã ã•ã„',
+ 'Filename' : 'ファイルå',
+ 'Status' : 'ステータス',
+ 'Size' : 'サイズ',
+ 'Add Files' : 'ファイルを追加',
+ 'Stop Upload' : 'アップロードåœæ­¢',
+ 'Start Upload' : 'アップロード',
+ 'Add files' : 'ファイルを追加',
+ 'Add files.' : 'ファイルを追加',
+ 'Stop current upload' : 'ç¾åœ¨ã®ã‚¢ãƒƒãƒ—ロードをåœæ­¢',
+ 'Start uploading queue' : 'アップロード',
+ 'Stop upload' : 'アップロードåœæ­¢',
+ 'Start upload' : 'アップロード',
+ 'Uploaded %d/%d files': 'アップロード中 %d/%d ファイル',
+ 'N/A' : 'N/A',
+ 'Drag files here.' : 'ã“ã“ã«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ドラッグ',
+ 'File extension error.': 'ファイル拡張å­ã‚¨ãƒ©ãƒ¼',
+ 'File size error.': 'ファイルサイズエラー',
+ 'File count error.': 'ファイル数エラー',
+ 'Init error.': 'イニシャライズエラー',
+ 'HTTP Error.': 'HTTP エラー',
+ 'Security error.': 'セキュリティエラー',
+ 'Generic error.': 'エラー',
+ 'IO error.': 'IO エラー',
+ 'File: %s': 'ファイル: %s',
+ 'Close': 'é–‰ã˜ã‚‹',
+ '%d files queued': '%d ファイルãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ',
+ 'Using runtime: ': 'モード: ',
+ 'File: %f, size: %s, max file size: %m': 'ファイル: %f, サイズ: %s, 最大ファイルサイズ: %m',
+ 'Upload element accepts only %d file(s) at a time. Extra files were stripped.': 'アップロードå¯èƒ½ãªãƒ•ã‚¡ã‚¤ãƒ«æ•°ã¯ %d ã§ã™ã€‚余分ãªãƒ•ã‚¡ã‚¤ãƒ«ã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸ',
+ 'Upload URL might be wrong or doesn\'t exist': 'アップロード先㮠URL ãŒå­˜åœ¨ã—ã¾ã›ã‚“',
+ 'Error: File too large: ': 'エラー: サイズãŒå¤§ãã™ãŽã¾ã™: ',
+ 'Error: Invalid file extension: ': 'エラー: æ‹¡å¼µå­ãŒè¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“: '
+});
diff --git a/debian/missing-sources/plupload/javascript/i18n/ko.js b/debian/missing-sources/plupload/javascript/i18n/ko.js
new file mode 100644
index 0000000..a2c5e66
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/ko.js
@@ -0,0 +1,36 @@
+// Republic of Korea
+plupload.addI18n({
+ 'Select files' : 'íŒŒì¼ ì„ íƒ',
+ 'Add files to the upload queue and click the start button.' : '파ì¼ì„ 업로드 íì— ì¶”ê°€í•˜ì—¬ 시작 ë²„íŠ¼ì„ í´ë¦­í•˜ì‹­ì‹œì˜¤.',
+ 'Filename' : 'íŒŒì¼ ì´ë¦„',
+ 'Status' : 'ìƒíƒœ',
+ 'Size' : 'í¬ê¸°',
+ 'Add Files' : 'íŒŒì¼ ì¶”ê°€',
+ 'Stop Upload': '업로드 중지',
+ 'Start Upload': '업로드',
+ 'Add files': 'íŒŒì¼ ì¶”ê°€',
+ 'Stop current upload': '현재 업로드를 정지',
+ 'Start uploading queue': '업로드',
+ 'Stop upload': '업로드 중지',
+ 'Start upload': '업로드',
+ 'Uploaded % d / % d files': '업로드 중 % d / % d 파ì¼',
+ 'N / A': 'N / A',
+ 'Drag files here': 'ì—¬ê¸°ì— íŒŒì¼ì„ 드래그',
+ 'File extension error': 'íŒŒì¼ í™•ìž¥ìž ì˜¤ë¥˜',
+ 'File size error': 'íŒŒì¼ í¬ê¸° 오류',
+ 'File count error': 'ì´ë¯¸ì§€ : 오류',
+ 'Init error': '초기화 오류',
+ 'HTTP Error': 'HTTP 오류',
+ 'Security error': '보안 오류',
+ 'Generic error': '오류',
+ 'IO error': 'IO 오류',
+ 'File : % s': 'íŒŒì¼ % s',
+ 'Close': '닫기',
+ '% d files queued': '% d 파ì¼ì´ 추가ë˜ì—ˆìŠµë‹ˆë‹¤',
+ 'Using runtime :': '모드',
+ 'File : % f, size : % s, max file size : % m': 'íŒŒì¼ : % f, í¬ê¸° : % s, 최대 íŒŒì¼ í¬ê¸° : % m',
+ 'Upload element accepts only % d file (s) at a time. Extra files were stripped': '업로드 가능한 파ì¼ì˜ 수는 % d입니다. 불필요한 파ì¼ì€ ì‚­ì œë˜ì—ˆìŠµë‹ˆë‹¤ ',
+ 'Upload URL might be wrong or doesn \'t exist ':'업로드할 URLì´ ì¡´ìž¬í•˜ì§€ 않습니다 ',
+ 'Error : File too large :': '오류 : í¬ê¸°ê°€ 너무 í½ë‹ˆë‹¤',
+ 'Error : Invalid file extension :': '오류 : 확장ìžê°€ 허용ë˜ì§€ 않습니다 :'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/lv.js b/debian/missing-sources/plupload/javascript/i18n/lv.js
new file mode 100644
index 0000000..2a04045
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/lv.js
@@ -0,0 +1,33 @@
+// .lv file like language pack
+plupload.addI18n({
+ 'Select files' : 'Izvēlieties failus',
+ 'Add files to the upload queue and click the start button.' : 'Pieveinojiet failus rindai un klikÅ¡Ä·iniet uz "SÄkt augÅ¡upielÄdi" pogas.',
+ 'Filename' : 'Faila nosaukums',
+ 'Status' : 'Statuss',
+ 'Size' : 'Izmērs',
+ 'Add files' : 'Pievienot failus',
+ 'Stop current upload' : 'ApturÄ“t paÅ¡reizÄ“jo augÅ¡upielÄdi',
+ 'Start uploading queue' : 'SÄkt augÅ¡upielÄdi',
+ 'Drag files here.' : 'Ievelciet failus Å¡eit',
+ 'Start upload' : 'SÄkt augÅ¡upielÄdi',
+ 'Uploaded %d/%d files': 'AugÅ¡upielÄdÄ“ti %d/%d faili',
+ 'Stop upload': 'PÄrtraukt augÅ¡upielÄdi',
+ 'Start upload': 'SÄkt augÅ¡upielÄdi',
+ '%d files queued': '%d faili pievienoti rindai',
+ 'File: %s': 'Fails: %s',
+ 'Close': 'Aizvērt',
+ 'Using runtime: ': 'Lieto saskarni: ',
+ 'File: %f, size: %s, max file size: %m': 'Fails: %f, izmÄ“rs: %s, maksimÄlais faila izmÄ“rs: %m',
+ 'Upload element accepts only %d file(s) at a time. Extra files were stripped.': 'IespÄ“jams ielÄdÄ“t tikai %d failus vienÄ reizÄ“. AtlikuÅ¡ie faili netika pievienoti',
+ 'Upload URL might be wrong or doesn\'t exist': 'AugÅ¡upielÄdes URL varÄ“tu bÅ«t nepareizs vai neeksistÄ“',
+ 'Error: File too large: ': 'Kļūda: Fails pÄrÄk liels: ',
+ 'Error: Invalid file extension: ': 'Kļūda: Nekorekts faila paplaÅ¡inÄjums:',
+ 'File extension error.': 'Faila paplaÅ¡inÄjuma kļūda.',
+ 'File size error.': 'Faila izmēra kļūda.',
+ 'File count error.': 'Failu skaita kļūda',
+ 'Init error.': 'InicializÄcijas kļūda.',
+ 'HTTP Error.': 'HTTP kļūda.',
+ 'Security error.': 'Drošības kļūda.',
+ 'Generic error.': 'VispÄrÄ“ja rakstura kļūda.',
+ 'IO error.': 'Ievades/Izvades kļūda.'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/nl.js b/debian/missing-sources/plupload/javascript/i18n/nl.js
new file mode 100644
index 0000000..8372c88
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/nl.js
@@ -0,0 +1,21 @@
+// Dutch
+plupload.addI18n({
+ 'Select files' : 'Selecteer bestand(en):',
+ 'Add files to the upload queue and click the start button.' : 'Voeg bestanden toe aan de wachtrij en druk op \'Start\'.',
+ 'Filename' : 'Bestandsnaam',
+ 'Status' : 'Status',
+ 'Size' : 'Grootte',
+ 'Add files' : 'Voeg bestanden toe',
+ 'Stop current upload' : 'Stop upload',
+ 'Start uploading queue' : 'Start upload',
+ 'Uploaded %d/%d files': '%d/%d bestanden ge-upload',
+ 'N/A' : 'Niet beschikbaar',
+ 'Drag files here.' : 'Sleep bestanden hierheen.',
+ 'File extension error.': 'Ongeldig bestandstype.',
+ 'File size error.': 'Bestandsgrootte Error.',
+ 'Init error.': 'Initialisatie error.',
+ 'HTTP Error.': 'HTTP Error.',
+ 'Security error.': 'Beveiliging error.',
+ 'Generic error.': 'Onbekende error.',
+ 'IO error.': 'IO error.'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/pl.js b/debian/missing-sources/plupload/javascript/i18n/pl.js
new file mode 100644
index 0000000..3d1b9be
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/pl.js
@@ -0,0 +1,24 @@
+plupload.addI18n({
+'Select files' : 'Wybierz pliki:',
+'Add files to the upload queue and click the start button.' : 'Dodaj pliki i kliknij \'Rozpocznij transfer\'.',
+'Filename' : 'Nazwa pliku',
+'Status' : 'Status',
+'Size' : 'Rozmiar',
+'Add files' : 'Dodaj pliki',
+'Stop current upload' : 'Przerwij aktualny transfer',
+'Start uploading queue' : 'Rozpocznij wysyłanie',
+'Uploaded %d/%d files': 'Wysłano %d/%d plików',
+'N/A' : 'Nie dostępne',
+'Drag files here.' : 'PrzeciÄ…gnij tu pliki',
+'File extension error.': 'Nieobsługiwany format pliku.',
+'File size error.': 'Plik jest zbyt duży.',
+'Init error.': 'BÅ‚Ä…d inicjalizacji.',
+'HTTP Error.': 'BÅ‚Ä…d HTTP.',
+'Security error.': 'Błąd bezpieczeństwa.',
+'Generic error.': 'Błąd ogólny.',
+'IO error.': 'BÅ‚Ä…d IO.',
+'Stop Upload': 'Przerwij transfer.',
+'Add Files': 'Dodaj pliki',
+'Start upload': 'Rozpocznij transfer.',
+'%d files queued': '%d plików w kolejce.'
+});
diff --git a/debian/missing-sources/plupload/javascript/i18n/pt-br.js b/debian/missing-sources/plupload/javascript/i18n/pt-br.js
new file mode 100644
index 0000000..9f34a64
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/pt-br.js
@@ -0,0 +1,35 @@
+// Brazilian Portuguese
+plupload.addI18n({
+ 'Select files' : 'Escolha os arquivos',
+ 'Add files to the upload queue and click the start button.' : 'Adicione os arquivos abaixo e clique no botão "Iniciar o envio".',
+ 'Filename' : 'Nome do arquivo',
+ 'Status' : 'Status',
+ 'Size' : 'Tamanho',
+ 'Add Files' : 'Adicionar arquivo(s)',
+ 'Stop Upload' : 'Parar o envio',
+ 'Start Upload' : 'Iniciar o envio',
+ 'Add files' : 'Adicionar arquivo(s)',
+ 'Add files.' : 'Adicionar arquivo(s)',
+ 'Stop upload' : 'Parar o envio',
+ 'Start upload' : 'Iniciar o envio',
+ 'Uploaded %d/%d files': 'Enviado(s) %d/%d arquivo(s)',
+ 'N/A' : 'N/D',
+ 'Drag files here.' : 'Arraste os arquivos pra cá',
+ 'File extension error.': 'Tipo de arquivo não permitido.',
+ 'File size error.': 'Tamanho de arquivo não permitido.',
+ 'File count error.': 'Erro na contagem dos arquivos',
+ 'Init error.': 'Erro inicializando.',
+ 'HTTP Error.': 'Erro HTTP.',
+ 'Security error.': 'Erro de segurança.',
+ 'Generic error.': 'Erro genérico.',
+ 'IO error.': 'Erro de E/S.',
+ 'File: %s': 'Arquivo: %s',
+ 'Close': 'Fechar',
+ '%d files queued': '%d arquivo(s)',
+ 'Using runtime: ': 'Usando: ',
+ 'File: %f, size: %s, max file size: %m': 'Arquivo: %f, tamanho: %s, máximo: %m',
+ 'Upload element accepts only %d file(s) at a time. Extra files were stripped.': 'Só são aceitos %d arquivos por vez. O que passou disso foi descartado.',
+ 'Upload URL might be wrong or doesn\'t exist': 'URL de envio está errada ou não existe',
+ 'Error: File too large: ': 'Erro: Arquivo muito grande: ',
+ 'Error: Invalid file extension: ': 'Erro: Tipo de arquivo não permitido: '
+});
diff --git a/debian/missing-sources/plupload/javascript/i18n/ro.js b/debian/missing-sources/plupload/javascript/i18n/ro.js
new file mode 100644
index 0000000..fd198f0
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/ro.js
@@ -0,0 +1,24 @@
+// Romanian
+plupload.addI18n({
+ 'Select files' : 'Selectare fiÅŸiere',
+ 'Add files to the upload queue and click the start button.' : 'Adaugă fişiere în lista apoi apasă butonul \'Începe încărcare\'.',
+ 'Filename' : 'Nume fiÅŸier',
+ 'Status' : 'Stare',
+ 'Size' : 'Mărime',
+ 'Add files' : 'Adăugare fişiere',
+ 'Stop current upload' : 'Întrerupe încărcarea curentă',
+ 'Start uploading queue' : 'Începe incărcarea',
+ 'Uploaded %d/%d files': 'Fişiere încărcate %d/%d',
+ 'N/A' : 'N/A',
+ 'Drag files here.' : 'Trage aici fiÅŸierele',
+ 'File extension error.': 'Extensie fişier eronată',
+ 'File size error.': 'Eroare dimensiune fiÅŸier',
+ 'Init error.': 'Eroare iniţializare',
+ 'HTTP Error.': 'Eroare HTTP',
+ 'Security error.': 'Eroare securitate',
+ 'Generic error.': 'Eroare generică',
+ 'IO error.': 'Eroare Intrare/IeÅŸire',
+ 'Stop Upload': 'Oprire încărcare',
+ 'Start upload': 'Începe încărcare',
+ '%d files queued': '%d fiÅŸiere listate'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/ru.js b/debian/missing-sources/plupload/javascript/i18n/ru.js
new file mode 100644
index 0000000..86469c7
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/ru.js
@@ -0,0 +1,21 @@
+// Russian
+plupload.addI18n({
+ 'Select files' : 'Выберите файлы',
+ 'Add files to the upload queue and click the start button.' : 'Добавьте файлы в очередь и нажмите кнопку "Загрузить файлы".',
+ 'Filename' : 'Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°',
+ 'Status' : 'СтатуÑ',
+ 'Size' : 'Размер',
+ 'Add files' : 'Добавить файлы',
+ 'Stop current upload' : 'ОÑтановить загрузку',
+ 'Start uploading queue' : 'Загрузить файлы',
+ 'Uploaded %d/%d files': 'Загружено %d/%d файлов',
+ 'N/A' : 'N/D',
+ 'Drag files here.' : 'Перетащите файлы Ñюда.',
+ 'File extension error.': 'Ðеправильное раÑширение файла.',
+ 'File size error.': 'Ðеправильный размер файла.',
+ 'Init error.': 'Ошибка инициализации.',
+ 'HTTP Error.': 'Ошибка HTTP.',
+ 'Security error.': 'Ошибка безопаÑноÑти.',
+ 'Generic error.': 'ÐžÐ±Ñ‰Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°.',
+ 'IO error.': 'Ошибка ввода-вывода.'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/sk.js b/debian/missing-sources/plupload/javascript/i18n/sk.js
new file mode 100644
index 0000000..8b4b2d9
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/sk.js
@@ -0,0 +1,25 @@
+// .po file like language pack
+plupload.addI18n({
+ 'Select files' : 'Vyberte súbory',
+ 'Add files to the upload queue and click the start button.' : 'Pridajte súbory do zoznamu a potom spustite nahrávanie.',
+ 'Filename' : 'Názov súboru',
+ 'Status' : 'Stav',
+ 'Size' : 'Veľkosť',
+ 'Add files' : 'Pridať súbory',
+ 'Stop current upload' : 'Zastaviť nahrávanie',
+ 'Start uploading queue' : 'Spustiť nahrávanie zoznamu',
+ 'Drag files here.' : 'Sem pretiahnite súbory.',
+ 'Start upload': 'Spustiť nahrávanie',
+ 'Uploaded %d/%d files': 'Nahraných %d/%d súborov',
+ 'Using runtime: ': 'K odoslaniu súborov sa použije rozhranie: ',
+ 'N/A' : 'N/A',
+ 'File extension error.': 'Chybný typ súboru.',
+ 'File size error.': 'Súbor je príliš veľký.',
+ 'Init error.': 'Chyba inicializácie.',
+ 'HTTP Error.': 'HTTP Chyba.',
+ 'Security error.': 'BezpeÄnostná Chyba.',
+ 'Generic error.': 'Chyba.',
+ 'IO error.': 'IO Chyba',
+ 'Stop Upload': 'Zastaviť nahrávanie',
+ '%d files queued': '%d súborov pridaných do zoznamu'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/sr.js b/debian/missing-sources/plupload/javascript/i18n/sr.js
new file mode 100644
index 0000000..59dc0a9
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/sr.js
@@ -0,0 +1,14 @@
+// Serbian
+plupload.addI18n({
+ 'Select files' : 'Izaberite fajlove',
+ 'Add files to the upload queue and click the start button.' : 'Dodajte fajlove u listu i kliknite na dugme Start.',
+ 'Filename' : 'Naziv fajla',
+ 'Status' : 'Status',
+ 'Size' : 'VeliÄina',
+ 'Add Files' : 'Dodaj fajlove',
+ 'Stop current upload' : 'Zaustavi upload',
+ 'Start uploading queue' : 'PoÄni upload',
+ 'Drag files here.' : 'Prevucite fajlove ovde.',
+ 'Start Upload': 'PoÄni upload',
+ 'Uploaded %d/%d files': 'Snimljeno %d/%d fajlova'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/i18n/sv.js b/debian/missing-sources/plupload/javascript/i18n/sv.js
new file mode 100644
index 0000000..11c7524
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/i18n/sv.js
@@ -0,0 +1,12 @@
+// .po file like language pack
+plupload.addI18n({
+ 'Select files' : 'Välj filer',
+ 'Add files to the upload queue and click the start button.' : 'Lägg till filer till kön och tryck på start.',
+ 'Filename' : 'Filnamn',
+ 'Status' : 'Status',
+ 'Size' : 'Storlek',
+ 'Add files' : 'Lägg till filer',
+ 'Stop current upload' : 'Stoppa uppladdningen',
+ 'Start uploading queue' : 'Starta uppladdningen',
+ 'Drag files here.' : 'Dra filer hit'
+}); \ No newline at end of file
diff --git a/debian/missing-sources/plupload/javascript/jquery.plupload.queue/css/jquery.plupload.queue.css b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/css/jquery.plupload.queue.css
new file mode 100644
index 0000000..8581fdd
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/css/jquery.plupload.queue.css
@@ -0,0 +1,177 @@
+/*
+ Plupload
+------------------------------------------------------------------- */
+
+.plupload_button {
+ display: -moz-inline-box; /* FF < 3*/
+ display: inline-block;
+ font: normal 12px sans-serif;
+ text-decoration: none;
+ color: #42454a;
+ border: 1px solid #bababa;
+ padding: 2px 8px 3px 20px;
+ margin-right: 4px;
+ background: #f3f3f3 url('../img/buttons.png') no-repeat 0 center;
+ outline: 0;
+
+ /* Optional rounded corners for browsers that support it */
+ -moz-border-radius: 3px;
+ -khtml-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+}
+
+.plupload_button:hover {
+ color: #000;
+ text-decoration: none;
+}
+
+.plupload_disabled, a.plupload_disabled:hover {
+ color: #737373;
+ border-color: #c5c5c5;
+ background: #ededed url('../img/buttons-disabled.png') no-repeat 0 center;
+ cursor: default;
+}
+
+.plupload_add {
+ background-position: -181px center;
+}
+
+.plupload_wrapper {
+ font: normal 11px Verdana,sans-serif;
+ width: 100%;
+}
+
+.plupload_container {
+ padding: 8px;
+ background: url('../img/transp50.png');
+ /*-moz-border-radius: 5px;*/
+}
+
+.plupload_container input {
+ border: 1px solid #DDD;
+ font: normal 11px Verdana,sans-serif;
+ width: 98%;
+}
+
+.plupload_header {background: #2A2C2E url('../img/backgrounds.gif') repeat-x;}
+.plupload_header_content {
+ background: url('../img/backgrounds.gif') no-repeat 0 -317px;
+ min-height: 56px;
+ padding-left: 60px;
+ color: #FFF;
+}
+.plupload_header_title {
+ font: normal 18px sans-serif;
+ padding: 6px 0 3px;
+}
+.plupload_header_text {
+ font: normal 12px sans-serif;
+}
+
+.plupload_filelist {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.plupload_scroll .plupload_filelist {
+ height: 185px;
+ background: #F5F5F5;
+ overflow-y: scroll;
+}
+
+.plupload_filelist li {
+ padding: 10px 8px;
+ background: #F5F5F5 url('../img/backgrounds.gif') repeat-x 0 -156px;
+ border-bottom: 1px solid #DDD;
+}
+
+.plupload_filelist_header, .plupload_filelist_footer {
+ background: #DFDFDF;
+ padding: 8px 8px;
+ color: #42454A;
+}
+.plupload_filelist_header {
+ border-top: 1px solid #EEE;
+ border-bottom: 1px solid #CDCDCD;
+}
+
+.plupload_filelist_footer {border-top: 1px solid #FFF; height: 22px; line-height: 20px; vertical-align: middle;}
+.plupload_file_name {float: left; overflow: hidden}
+.plupload_file_status {color: #777;}
+.plupload_file_status span {color: #42454A;}
+.plupload_file_size, .plupload_file_status, .plupload_progress {
+ float: right;
+ width: 80px;
+}
+.plupload_file_size, .plupload_file_status, .plupload_file_action {text-align: right;}
+
+.plupload_filelist .plupload_file_name {width: 205px}
+
+.plupload_file_action {
+ float: right;
+ width: 16px;
+ height: 16px;
+ margin-left: 15px;
+}
+
+.plupload_file_action * {
+ display: none;
+ width: 16px;
+ height: 16px;
+}
+
+li.plupload_uploading {background: #ECF3DC url('../img/backgrounds.gif') repeat-x 0 -238px;}
+li.plupload_done {color:#AAA}
+
+li.plupload_delete a {
+ background: url('../img/delete.gif');
+}
+
+li.plupload_failed a {
+ background: url('../img/error.gif');
+ cursor: default;
+}
+
+li.plupload_done a {
+ background: url('../img/done.gif');
+ cursor: default;
+}
+
+.plupload_progress, .plupload_upload_status {
+ display: none;
+}
+
+.plupload_progress_container {
+ margin-top: 3px;
+ border: 1px solid #CCC;
+ background: #FFF;
+ padding: 1px;
+}
+.plupload_progress_bar {
+ width: 0px;
+ height: 7px;
+ background: #CDEB8B;
+}
+
+.plupload_scroll .plupload_filelist_header .plupload_file_action, .plupload_scroll .plupload_filelist_footer .plupload_file_action {
+ margin-right: 17px;
+}
+
+/* Floats */
+
+.plupload_clear,.plupload_clearer {clear: both;}
+.plupload_clearer, .plupload_progress_bar {
+ display: block;
+ font-size: 0;
+ line-height: 0;
+}
+
+li.plupload_droptext {
+ background: transparent;
+ text-align: center;
+ vertical-align: middle;
+ border: 0;
+ line-height: 165px;
+}
diff --git a/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/backgrounds.gif b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/backgrounds.gif
new file mode 100644
index 0000000..39e33eb
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/backgrounds.gif
Binary files differ
diff --git a/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/buttons-disabled.png b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/buttons-disabled.png
new file mode 100644
index 0000000..afa11af
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/buttons-disabled.png
Binary files differ
diff --git a/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/buttons.png b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/buttons.png
new file mode 100644
index 0000000..153e738
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/buttons.png
Binary files differ
diff --git a/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/delete.gif b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/delete.gif
new file mode 100644
index 0000000..78ca8b3
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/delete.gif
Binary files differ
diff --git a/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/done.gif b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/done.gif
new file mode 100644
index 0000000..29f3ed7
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/done.gif
Binary files differ
diff --git a/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/error.gif b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/error.gif
new file mode 100644
index 0000000..4682b63
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/error.gif
Binary files differ
diff --git a/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/throbber.gif b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/throbber.gif
new file mode 100644
index 0000000..4ae8b16
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/throbber.gif
Binary files differ
diff --git a/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/transp50.png b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/transp50.png
new file mode 100644
index 0000000..eb0efe1
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/img/transp50.png
Binary files differ
diff --git a/debian/missing-sources/plupload/javascript/jquery.plupload.queue/jquery.plupload.queue.js b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/jquery.plupload.queue.js
new file mode 100644
index 0000000..0de6a1c
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/jquery.plupload.queue/jquery.plupload.queue.js
@@ -0,0 +1,336 @@
+/**
+ * jquery.plupload.queue.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global plupload:false, jQuery:false, alert:false */
+
+(function($) {
+ var uploaders = {};
+
+ function _(str) {
+ return plupload.translate(str) || str;
+ }
+
+ function renderUI(id, target) {
+ // Remove all existing non plupload items
+ target.contents().each(function(i, node) {
+ node = $(node);
+
+ if (!node.is('.plupload')) {
+ node.remove();
+ }
+ });
+
+ target.prepend(
+ '<div class="plupload_wrapper plupload_scroll">' +
+ '<div id="' + id + '_container" class="plupload_container">' +
+ '<div class="plupload">' +
+ '<div class="plupload_header">' +
+ '<div class="plupload_header_content">' +
+ '<div class="plupload_header_title">' + _('Select files') + '</div>' +
+ '<div class="plupload_header_text">' + _('Add files to the upload queue and click the start button.') + '</div>' +
+ '</div>' +
+ '</div>' +
+
+ '<div class="plupload_content">' +
+ '<div class="plupload_filelist_header">' +
+ '<div class="plupload_file_name">' + _('Filename') + '</div>' +
+ '<div class="plupload_file_action">&nbsp;</div>' +
+ '<div class="plupload_file_status"><span>' + _('Status') + '</span></div>' +
+ '<div class="plupload_file_size">' + _('Size') + '</div>' +
+ '<div class="plupload_clearer">&nbsp;</div>' +
+ '</div>' +
+
+ '<ul id="' + id + '_filelist" class="plupload_filelist"></ul>' +
+
+ '<div class="plupload_filelist_footer">' +
+ '<div class="plupload_file_name">' +
+ '<div class="plupload_buttons">' +
+ '<a href="#" class="plupload_button plupload_add">' + _('Add files') + '</a>' +
+ '<a href="#" class="plupload_button plupload_start">' + _('Start upload') + '</a>' +
+ '</div>' +
+ '<span class="plupload_upload_status"></span>' +
+ '</div>' +
+ '<div class="plupload_file_action"></div>' +
+ '<div class="plupload_file_status"><span class="plupload_total_status">0%</span></div>' +
+ '<div class="plupload_file_size"><span class="plupload_total_file_size">0 b</span></div>' +
+ '<div class="plupload_progress">' +
+ '<div class="plupload_progress_container">' +
+ '<div class="plupload_progress_bar"></div>' +
+ '</div>' +
+ '</div>' +
+ '<div class="plupload_clearer">&nbsp;</div>' +
+ '</div>' +
+ '</div>' +
+ '</div>' +
+ '</div>' +
+ '<input type="hidden" id="' + id + '_count" name="' + id + '_count" value="0" />' +
+ '</div>'
+ );
+ }
+
+ $.fn.pluploadQueue = function(settings) {
+ if (settings) {
+ this.each(function() {
+ var uploader, target, id;
+
+ target = $(this);
+ id = target.attr('id');
+
+ if (!id) {
+ id = plupload.guid();
+ target.attr('id', id);
+ }
+
+ uploader = new plupload.Uploader($.extend({
+ dragdrop : true,
+ container : id
+ }, settings));
+
+ uploaders[id] = uploader;
+
+ function handleStatus(file) {
+ var actionClass;
+
+ if (file.status == plupload.DONE) {
+ actionClass = 'plupload_done';
+ }
+
+ if (file.status == plupload.FAILED) {
+ actionClass = 'plupload_failed';
+ }
+
+ if (file.status == plupload.QUEUED) {
+ actionClass = 'plupload_delete';
+ }
+
+ if (file.status == plupload.UPLOADING) {
+ actionClass = 'plupload_uploading';
+ }
+
+ var icon = $('#' + file.id).attr('class', actionClass).find('a').css('display', 'block');
+ if (file.hint) {
+ icon.attr('title', file.hint);
+ }
+ }
+
+ function updateTotalProgress() {
+ $('span.plupload_total_status', target).html(uploader.total.percent + '%');
+ $('div.plupload_progress_bar', target).css('width', uploader.total.percent + '%');
+ $('span.plupload_upload_status', target).html(
+ _('Uploaded %d/%d files').replace(/%d\/%d/, uploader.total.uploaded+'/'+uploader.files.length)
+ );
+ }
+
+ function updateList() {
+ var fileList = $('ul.plupload_filelist', target).html(''), inputCount = 0, inputHTML;
+
+ $.each(uploader.files, function(i, file) {
+ inputHTML = '';
+
+ if (file.status == plupload.DONE) {
+ if (file.target_name) {
+ inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_tmpname" value="' + plupload.xmlEncode(file.target_name) + '" />';
+ }
+
+ inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_name" value="' + plupload.xmlEncode(file.name) + '" />';
+ inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_status" value="' + (file.status == plupload.DONE ? 'done' : 'failed') + '" />';
+
+ inputCount++;
+
+ $('#' + id + '_count').val(inputCount);
+ }
+
+ fileList.append(
+ '<li id="' + file.id + '">' +
+ '<div class="plupload_file_name"><span>' + file.name + '</span></div>' +
+ '<div class="plupload_file_action"><a href="#"></a></div>' +
+ '<div class="plupload_file_status">' + file.percent + '%</div>' +
+ '<div class="plupload_file_size">' + plupload.formatSize(file.size) + '</div>' +
+ '<div class="plupload_clearer">&nbsp;</div>' +
+ inputHTML +
+ '</li>'
+ );
+
+ handleStatus(file);
+
+ $('#' + file.id + '.plupload_delete a').click(function(e) {
+ $('#' + file.id).remove();
+ uploader.removeFile(file);
+
+ e.preventDefault();
+ });
+ });
+
+ $('span.plupload_total_file_size', target).html(plupload.formatSize(uploader.total.size));
+
+ if (uploader.total.queued === 0) {
+ $('span.plupload_add_text', target).html(_('Add files.'));
+ } else {
+ $('span.plupload_add_text', target).html(uploader.total.queued + ' files queued.');
+ }
+
+ $('a.plupload_start', target).toggleClass('plupload_disabled', uploader.files.length == (uploader.total.uploaded + uploader.total.failed));
+
+ // Scroll to end of file list
+ fileList[0].scrollTop = fileList[0].scrollHeight;
+
+ updateTotalProgress();
+
+ // Re-add drag message if there is no files
+ if (!uploader.files.length && uploader.features.dragdrop && uploader.settings.dragdrop) {
+ $('#' + id + '_filelist').append('<li class="plupload_droptext">' + _("Drag files here.") + '</li>');
+ }
+ }
+
+ uploader.bind("UploadFile", function(up, file) {
+ $('#' + file.id).addClass('plupload_current_file');
+ });
+
+ uploader.bind('Init', function(up, res) {
+ renderUI(id, target);
+
+ // Enable rename support
+ if (!settings.unique_names && settings.rename) {
+ target.on('click', '#' + id + '_filelist div.plupload_file_name span', function(e) {
+ var targetSpan = $(e.target), file, parts, name, ext = "";
+
+ // Get file name and split out name and extension
+ file = up.getFile(targetSpan.parents('li')[0].id);
+ name = file.name;
+ parts = /^(.+)(\.[^.]+)$/.exec(name);
+ if (parts) {
+ name = parts[1];
+ ext = parts[2];
+ }
+
+ // Display input element
+ targetSpan.hide().after('<input type="text" />');
+ targetSpan.next().val(name).focus().blur(function() {
+ targetSpan.show().next().remove();
+ }).keydown(function(e) {
+ var targetInput = $(this);
+
+ if ($.inArray(e.keyCode, [13, 27]) !== -1) {
+ e.preventDefault();
+
+ // Rename file and glue extension back on
+ if (e.keyCode === 13) {
+ file.name = targetInput.val() + ext;
+ targetSpan.html(file.name);
+ }
+ targetInput.blur();
+ }
+ });
+ });
+ }
+
+ $('a.plupload_add', target).attr('id', id + '_browse');
+
+ up.settings.browse_button = id + '_browse';
+
+ // Enable drag/drop
+ if (up.features.dragdrop && up.settings.dragdrop) {
+ up.settings.drop_element = id + '_filelist';
+ $('#' + id + '_filelist').append('<li class="plupload_droptext">' + _("Drag files here.") + '</li>');
+ }
+
+ $('#' + id + '_container').attr('title', 'Using runtime: ' + res.runtime);
+
+ $('a.plupload_start', target).click(function(e) {
+ if (!$(this).hasClass('plupload_disabled')) {
+ uploader.start();
+ }
+
+ e.preventDefault();
+ });
+
+ $('a.plupload_stop', target).click(function(e) {
+ e.preventDefault();
+ uploader.stop();
+ });
+
+ $('a.plupload_start', target).addClass('plupload_disabled');
+ });
+
+ uploader.init();
+
+ uploader.bind("Error", function(up, err) {
+ var file = err.file, message;
+
+ if (file) {
+ message = err.message;
+
+ if (err.details) {
+ message += " (" + err.details + ")";
+ }
+
+ if (err.code == plupload.FILE_SIZE_ERROR) {
+ alert(_("Error: File too large: ") + file.name);
+ }
+
+ if (err.code == plupload.FILE_EXTENSION_ERROR) {
+ alert(_("Error: Invalid file extension: ") + file.name);
+ }
+
+ file.hint = message;
+ $('#' + file.id).attr('class', 'plupload_failed').find('a').css('display', 'block').attr('title', message);
+ }
+ });
+
+ uploader.bind('StateChanged', function() {
+ if (uploader.state === plupload.STARTED) {
+ $('li.plupload_delete a,div.plupload_buttons', target).hide();
+ $('span.plupload_upload_status,div.plupload_progress,a.plupload_stop', target).css('display', 'block');
+ $('span.plupload_upload_status', target).html('Uploaded ' + uploader.total.uploaded + '/' + uploader.files.length + ' files');
+
+ if (settings.multiple_queues) {
+ $('span.plupload_total_status,span.plupload_total_file_size', target).show();
+ }
+ } else {
+ updateList();
+ $('a.plupload_stop,div.plupload_progress', target).hide();
+ $('a.plupload_delete', target).css('display', 'block');
+ }
+ });
+
+ uploader.bind('QueueChanged', updateList);
+
+ uploader.bind('FileUploaded', function(up, file) {
+ handleStatus(file);
+ });
+
+ uploader.bind("UploadProgress", function(up, file) {
+ // Set file specific progress
+ $('#' + file.id + ' div.plupload_file_status', target).html(file.percent + '%');
+
+ handleStatus(file);
+ updateTotalProgress();
+
+ if (settings.multiple_queues && uploader.total.uploaded + uploader.total.failed == uploader.files.length) {
+ $(".plupload_buttons,.plupload_upload_status", target).css("display", "inline");
+ $(".plupload_start", target).addClass("plupload_disabled");
+ $('span.plupload_total_status,span.plupload_total_file_size', target).hide();
+ }
+ });
+
+ // Call setup function
+ if (settings.setup) {
+ settings.setup(uploader);
+ }
+ });
+
+ return this;
+ } else {
+ // Get uploader instance for specified element
+ return uploaders[$(this[0]).attr('id')];
+ }
+ };
+})(jQuery);
diff --git a/debian/missing-sources/plupload/javascript/jquery.ui.plupload/css/jquery.ui.plupload.css b/debian/missing-sources/plupload/javascript/jquery.ui.plupload/css/jquery.ui.plupload.css
new file mode 100644
index 0000000..a819fff
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/jquery.ui.plupload/css/jquery.ui.plupload.css
@@ -0,0 +1,147 @@
+/*
+ Plupload
+------------------------------------------------------------------- */
+
+.plupload_button {cursor: pointer;}
+
+.plupload_wrapper {
+ font: normal 11px Verdana,sans-serif;
+ width: 100%;
+}
+
+.plupload .plupload_container input {width: 98%;}
+.plupload .plupload_filelist_footer {border-width: 1px 0 0 0}
+.plupload .plupload_filelist_header {border-width: 0 0 1px 0}
+div.plupload .plupload_file {border-width: 0 0 1px 0}
+div.plupload div.plupload_header {border-width: 0 0 1px 0; position: relative;}
+
+.plupload_file .ui-icon {
+ cursor:pointer;
+}
+
+.plupload_header_content {
+ background-image: url('../img/plupload.png');
+ background-repeat: no-repeat;
+ background-position: 8px center;
+ min-height: 56px;
+ padding-left: 60px;
+ position:relative;
+}
+.plupload_header_content_bw {background-image: url('../img/plupload-bw.png');}
+.plupload_header_title {
+ font: normal 18px sans-serif;
+ padding: 6px 0 3px;
+}
+.plupload_header_text {font: normal 12px sans-serif;}
+
+.plupload_filelist,
+.plupload_filelist_content {
+ border-collapse: collapse;
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ -moz-user-select:none;
+ -webkit-user-select:none;
+ user-select:none;
+}
+
+.plupload_cell {padding: 8px 6px;}
+
+.plupload_file {
+ border-left: none;
+ border-right: none;
+}
+
+.plupload .ui-sortable-helper,
+.plupload .ui-sortable .plupload_file {
+ cursor:move;
+}
+
+.plupload_scroll {
+ max-height: 180px;
+ min-height: 168px;
+ _height: 168px;
+ overflow-y: auto;
+}
+
+.plupload_file_size, .plupload_file_status {text-align: right;}
+.plupload_file_size, .plupload_file_status {width: 52px;}
+.plupload_file_action {width: 16px;}
+.plupload_file_name {
+ overflow: hidden;
+ padding-left: 10px;
+}
+
+.plupload_file_rename {
+ width:95%;
+}
+
+.plupload_progress {width: 60px;}
+.plupload_progress_container {padding: 1px;}
+
+
+/* Floats */
+
+.plupload_right {float: right;}
+.plupload_left {float: left;}
+.plupload_clear,.plupload_clearer {clear: both;}
+.plupload_clearer, .plupload_progress_bar {
+ display: block;
+ font-size: 0;
+ line-height: 0;
+}
+.plupload_clearer {height: 0;}
+
+/* Misc */
+.plupload_hidden {display: none;}
+.plupload_droptext {
+ background: transparent;
+ text-align: center;
+ vertical-align: middle;
+ border: 0;
+ line-height: 165px;
+}
+
+.plupload_buttons, .plupload_upload_status {float: left}
+
+.plupload_message {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ height: 100%;
+ width: 100%;
+}
+
+.plupload_message p {
+ padding:0.7em;
+ margin:0;
+}
+
+.plupload_message strong {
+ font-weight: bold;
+}
+
+plupload_message i {
+ font-style: italic;
+}
+
+.plupload_message p span.ui-icon {
+ float: left;
+ margin-right: 0.3em;
+}
+
+.plupload_header_content .ui-state-error,
+.plupload_header_content .ui-state-highlight {
+ border:none;
+}
+
+.plupload_message_close {
+ position:absolute;
+ top:5px;
+ right:5px;
+ cursor:pointer;
+}
+
+.plupload .ui-sortable-placeholder {
+ height:35px;
+}
diff --git a/debian/missing-sources/plupload/javascript/jquery.ui.plupload/img/plupload-bw.png b/debian/missing-sources/plupload/javascript/jquery.ui.plupload/img/plupload-bw.png
new file mode 100644
index 0000000..bb4147e
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/jquery.ui.plupload/img/plupload-bw.png
Binary files differ
diff --git a/debian/missing-sources/plupload/javascript/jquery.ui.plupload/img/plupload.png b/debian/missing-sources/plupload/javascript/jquery.ui.plupload/img/plupload.png
new file mode 100644
index 0000000..74fa3ad
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/jquery.ui.plupload/img/plupload.png
Binary files differ
diff --git a/debian/missing-sources/plupload/javascript/jquery.ui.plupload/jquery.ui.plupload.js b/debian/missing-sources/plupload/javascript/jquery.ui.plupload/jquery.ui.plupload.js
new file mode 100644
index 0000000..9efafd4
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/jquery.ui.plupload/jquery.ui.plupload.js
@@ -0,0 +1,754 @@
+/**
+ * jquery.ui.plupload.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ *
+ * Optionally:
+ * jquery.ui.button.js
+ * jquery.ui.progressbar.js
+ * jquery.ui.sortable.js
+ */
+
+// JSLint defined globals
+/*global window:false, document:false, plupload:false, jQuery:false */
+
+(function(window, document, plupload, $, undef) {
+
+var uploaders = {};
+
+function _(str) {
+ return plupload.translate(str) || str;
+}
+
+function renderUI(obj) {
+ obj.html(
+ '<div class="plupload_wrapper">' +
+ '<div class="ui-widget-content plupload_container">' +
+ '<div class="plupload">' +
+ '<div class="ui-state-default ui-widget-header plupload_header">' +
+ '<div class="plupload_header_content">' +
+ '<div class="plupload_header_title">' + _('Select files') + '</div>' +
+ '<div class="plupload_header_text">' + _('Add files to the upload queue and click the start button.') + '</div>' +
+ '</div>' +
+ '</div>' +
+
+ '<div class="plupload_content">' +
+ '<table class="plupload_filelist">' +
+ '<tr class="ui-widget-header plupload_filelist_header">' +
+ '<td class="plupload_cell plupload_file_name">' + _('Filename') + '</td>' +
+ '<td class="plupload_cell plupload_file_status">' + _('Status') + '</td>' +
+ '<td class="plupload_cell plupload_file_size">' + _('Size') + '</td>' +
+ '<td class="plupload_cell plupload_file_action">&nbsp;</td>' +
+ '</tr>' +
+ '</table>' +
+
+ '<div class="plupload_scroll">' +
+ '<table class="plupload_filelist_content"></table>' +
+ '</div>' +
+
+ '<table class="plupload_filelist">' +
+ '<tr class="ui-widget-header ui-widget-content plupload_filelist_footer">' +
+ '<td class="plupload_cell plupload_file_name">' +
+
+ '<div class="plupload_buttons"><!-- Visible -->' +
+ '<a class="plupload_button plupload_add">' + _('Add Files') + '</a>&nbsp;' +
+ '<a class="plupload_button plupload_start">' + _('Start Upload') + '</a>&nbsp;' +
+ '<a class="plupload_button plupload_stop plupload_hidden">'+_('Stop Upload') + '</a>&nbsp;' +
+ '</div>' +
+
+ '<div class="plupload_started plupload_hidden"><!-- Hidden -->' +
+
+ '<div class="plupload_progress plupload_right">' +
+ '<div class="plupload_progress_container"></div>' +
+ '</div>' +
+
+ '<div class="plupload_cell plupload_upload_status"></div>' +
+
+ '<div class="plupload_clearer">&nbsp;</div>' +
+
+ '</div>' +
+ '</td>' +
+ '<td class="plupload_file_status"><span class="plupload_total_status">0%</span></td>' +
+ '<td class="plupload_file_size"><span class="plupload_total_file_size">0 kb</span></td>' +
+ '<td class="plupload_file_action"></td>' +
+ '</tr>' +
+ '</table>' +
+ '</div>' +
+ '</div>' +
+ '</div>' +
+ '<input class="plupload_count" value="0" type="hidden">' +
+ '</div>'
+ );
+}
+
+
+$.widget("ui.plupload", {
+
+ contents_bak: '',
+
+ runtime: null,
+
+ options: {
+ browse_button_hover: 'ui-state-hover',
+ browse_button_active: 'ui-state-active',
+
+ // widget specific
+ dragdrop : true,
+ multiple_queues: true, // re-use widget by default
+
+ buttons: {
+ browse: true,
+ start: true,
+ stop: true
+ },
+ autostart: false,
+ sortable: false,
+ rename: false,
+ max_file_count: 0 // unlimited
+ },
+
+ FILE_COUNT_ERROR: -9001,
+
+ _create: function() {
+ var self = this, id, uploader;
+
+ id = this.element.attr('id');
+ if (!id) {
+ id = plupload.guid();
+ this.element.attr('id', id);
+ }
+ this.id = id;
+
+ // backup the elements initial state
+ this.contents_bak = this.element.html();
+ renderUI(this.element);
+
+ // container, just in case
+ this.container = $('.plupload_container', this.element).attr('id', id + '_container');
+
+ // list of files, may become sortable
+ this.filelist = $('.plupload_filelist_content', this.container)
+ .attr({
+ id: id + '_filelist',
+ unselectable: 'on'
+ });
+
+ // buttons
+ this.browse_button = $('.plupload_add', this.container).attr('id', id + '_browse');
+ this.start_button = $('.plupload_start', this.container).attr('id', id + '_start');
+ this.stop_button = $('.plupload_stop', this.container).attr('id', id + '_stop');
+
+ if ($.ui.button) {
+ this.browse_button.button({
+ icons: { primary: 'ui-icon-circle-plus' }
+ });
+
+ this.start_button.button({
+ icons: { primary: 'ui-icon-circle-arrow-e' },
+ disabled: true
+ });
+
+ this.stop_button.button({
+ icons: { primary: 'ui-icon-circle-close' }
+ });
+ }
+
+ // progressbar
+ this.progressbar = $('.plupload_progress_container', this.container);
+
+ if ($.ui.progressbar) {
+ this.progressbar.progressbar();
+ }
+
+ // counter
+ this.counter = $('.plupload_count', this.element)
+ .attr({
+ id: id + '_count',
+ name: id + '_count'
+ });
+
+ // initialize uploader instance
+ uploader = this.uploader = uploaders[id] = new plupload.Uploader($.extend({
+ container: id ,
+ browse_button: id + '_browse'
+ }, this.options));
+
+ // do not show UI if no runtime can be initialized
+ uploader.bind('Error', function(up, err) {
+ if (err.code === plupload.INIT_ERROR) {
+ self.destroy();
+ }
+ });
+
+ uploader.bind('Init', function(up, res) {
+ // all buttons are optional, so they can be disabled and hidden
+ if (!self.options.buttons.browse) {
+ self.browse_button.button('disable').hide();
+ up.disableBrowse(true);
+ }
+
+ if (!self.options.buttons.start) {
+ self.start_button.button('disable').hide();
+ }
+
+ if (!self.options.buttons.stop) {
+ self.stop_button.button('disable').hide();
+ }
+
+ if (!self.options.unique_names && self.options.rename) {
+ self._enableRenaming();
+ }
+
+ if (uploader.features.dragdrop && self.options.dragdrop) {
+ self._enableDragAndDrop();
+ }
+
+ self.container.attr('title', _('Using runtime: ') + (self.runtime = res.runtime));
+
+ self.start_button.click(function(e) {
+ if (!$(this).button('option', 'disabled')) {
+ self.start();
+ }
+ e.preventDefault();
+ });
+
+ self.stop_button.click(function(e) {
+ self.stop();
+ e.preventDefault();
+ });
+ });
+
+
+ // check if file count doesn't exceed the limit
+ if (self.options.max_file_count) {
+ uploader.bind('FilesAdded', function(up, selectedFiles) {
+ var removed = [], selectedCount = selectedFiles.length;
+ var extraCount = up.files.length + selectedCount - self.options.max_file_count;
+
+ if (extraCount > 0) {
+ removed = selectedFiles.splice(selectedCount - extraCount, extraCount);
+
+ up.trigger('Error', {
+ code : self.FILE_COUNT_ERROR,
+ message : _('File count error.'),
+ file : removed
+ });
+ }
+ });
+ }
+
+ // uploader internal events must run first
+ uploader.init();
+
+ uploader.bind('FilesAdded', function(up, files) {
+ self._trigger('selected', null, { up: up, files: files } );
+
+ if (self.options.autostart) {
+ // set a little delay to make sure that QueueChanged triggered by the core has time to complete
+ setTimeout(function() {
+ self.start();
+ }, 10);
+ }
+ });
+
+ uploader.bind('FilesRemoved', function(up, files) {
+ self._trigger('removed', null, { up: up, files: files } );
+ });
+
+ uploader.bind('QueueChanged', function() {
+ self._updateFileList();
+ });
+
+ uploader.bind('StateChanged', function() {
+ self._handleState();
+ });
+
+ uploader.bind('UploadFile', function(up, file) {
+ self._handleFileStatus(file);
+ });
+
+ uploader.bind('FileUploaded', function(up, file) {
+ self._handleFileStatus(file);
+
+ self._trigger('uploaded', null, { up: up, file: file } );
+ });
+
+ uploader.bind('UploadProgress', function(up, file) {
+ // Set file specific progress
+ $('#' + file.id)
+ .find('.plupload_file_status')
+ .html(file.percent + '%')
+ .end()
+ .find('.plupload_file_size')
+ .html(plupload.formatSize(file.size));
+
+ self._handleFileStatus(file);
+ self._updateTotalProgress();
+
+ self._trigger('progress', null, { up: up, file: file } );
+ });
+
+ uploader.bind('UploadComplete', function(up, files) {
+ self._trigger('complete', null, { up: up, files: files } );
+ });
+
+ uploader.bind('Error', function(up, err) {
+ var file = err.file, message, details;
+
+ if (file) {
+ message = '<strong>' + err.message + '</strong>';
+ details = err.details;
+
+ if (details) {
+ message += " <br /><i>" + err.details + "</i>";
+ } else {
+
+ switch (err.code) {
+ case plupload.FILE_EXTENSION_ERROR:
+ details = _("File: %s").replace('%s', file.name);
+ break;
+
+ case plupload.FILE_SIZE_ERROR:
+ details = _("File: %f, size: %s, max file size: %m").replace(/%([fsm])/g, function($0, $1) {
+ switch ($1) {
+ case 'f': return file.name;
+ case 's': return file.size;
+ case 'm': return plupload.parseSize(self.options.max_file_size);
+ }
+ });
+ break;
+
+ case self.FILE_COUNT_ERROR:
+ details = _("Upload element accepts only %d file(s) at a time. Extra files were stripped.")
+ .replace('%d', self.options.max_file_count);
+ break;
+
+ case plupload.IMAGE_FORMAT_ERROR :
+ details = plupload.translate('Image format either wrong or not supported.');
+ break;
+
+ case plupload.IMAGE_MEMORY_ERROR :
+ details = plupload.translate('Runtime ran out of available memory.');
+ break;
+
+ case plupload.IMAGE_DIMENSIONS_ERROR :
+ details = plupload.translate('Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.').replace(/%([swh])/g, function($0, $1) {
+ switch ($1) {
+ case 's': return up.runtime;
+ case 'w': return up.features.maxWidth;
+ case 'h': return up.features.maxHeight;
+ }
+ });
+ break;
+
+ case plupload.HTTP_ERROR:
+ details = _("Upload URL might be wrong or doesn't exist");
+ break;
+ }
+ message += " <br /><i>" + details + "</i>";
+ }
+
+ self.notify('error', message);
+ self._trigger('error', null, { up: up, file: file, error: message } );
+ }
+ });
+ },
+
+ _setOption: function(key, value) {
+ var self = this;
+
+ if (key == 'buttons' && typeof(value) == 'object') {
+ value = $.extend(self.options.buttons, value);
+
+ if (!value.browse) {
+ self.browse_button.button('disable').hide();
+ up.disableBrowse(true);
+ } else {
+ self.browse_button.button('enable').show();
+ up.disableBrowse(false);
+ }
+
+ if (!value.start) {
+ self.start_button.button('disable').hide();
+ } else {
+ self.start_button.button('enable').show();
+ }
+
+ if (!value.stop) {
+ self.stop_button.button('disable').hide();
+ } else {
+ self.start_button.button('enable').show();
+ }
+ }
+
+ self.uploader.settings[key] = value;
+ },
+
+
+ start: function() {
+ this.uploader.start();
+ this._trigger('start', null);
+ },
+
+ stop: function() {
+ this.uploader.stop();
+ this._trigger('stop', null);
+ },
+
+ getFile: function(id) {
+ var file;
+
+ if (typeof id === 'number') {
+ file = this.uploader.files[id];
+ } else {
+ file = this.uploader.getFile(id);
+ }
+ return file;
+ },
+
+ removeFile: function(id) {
+ var file = this.getFile(id);
+ if (file) {
+ this.uploader.removeFile(file);
+ }
+ },
+
+ clearQueue: function() {
+ this.uploader.splice();
+ },
+
+ getUploader: function() {
+ return this.uploader;
+ },
+
+ refresh: function() {
+ this.uploader.refresh();
+ },
+
+
+ _handleState: function() {
+ var self = this, up = this.uploader;
+
+ if (up.state === plupload.STARTED) {
+
+ $(self.start_button).button('disable');
+
+ $([])
+ .add(self.stop_button)
+ .add('.plupload_started')
+ .removeClass('plupload_hidden');
+
+ $('.plupload_upload_status', self.element).html(
+ _('Uploaded %d/%d files').replace('%d/%d', up.total.uploaded+'/'+up.files.length)
+ );
+
+ $('.plupload_header_content', self.element).addClass('plupload_header_content_bw');
+
+ } else {
+
+ $([])
+ .add(self.stop_button)
+ .add('.plupload_started')
+ .addClass('plupload_hidden');
+
+ if (self.options.multiple_queues) {
+ $(self.start_button).button('enable');
+
+ $('.plupload_header_content', self.element).removeClass('plupload_header_content_bw');
+ }
+
+ self._updateFileList();
+ }
+ },
+
+
+ _handleFileStatus: function(file) {
+ var actionClass, iconClass;
+
+ // since this method might be called asynchronously, file row might not yet be rendered
+ if (!$('#' + file.id).length) {
+ return;
+ }
+
+ switch (file.status) {
+ case plupload.DONE:
+ actionClass = 'plupload_done';
+ iconClass = 'ui-icon ui-icon-circle-check';
+ break;
+
+ case plupload.FAILED:
+ actionClass = 'ui-state-error plupload_failed';
+ iconClass = 'ui-icon ui-icon-alert';
+ break;
+
+ case plupload.QUEUED:
+ actionClass = 'plupload_delete';
+ iconClass = 'ui-icon ui-icon-circle-minus';
+ break;
+
+ case plupload.UPLOADING:
+ actionClass = 'ui-state-highlight plupload_uploading';
+ iconClass = 'ui-icon ui-icon-circle-arrow-w';
+
+ // scroll uploading file into the view if its bottom boundary is out of it
+ var scroller = $('.plupload_scroll', this.container),
+ scrollTop = scroller.scrollTop(),
+ scrollerHeight = scroller.height(),
+ rowOffset = $('#' + file.id).position().top + $('#' + file.id).height();
+
+ if (scrollerHeight < rowOffset) {
+ scroller.scrollTop(scrollTop + rowOffset - scrollerHeight);
+ }
+ break;
+ }
+ actionClass += ' ui-state-default plupload_file';
+
+ $('#' + file.id)
+ .attr('class', actionClass)
+ .find('.ui-icon')
+ .attr('class', iconClass);
+ },
+
+
+ _updateTotalProgress: function() {
+ var up = this.uploader;
+
+ this.progressbar.progressbar('value', up.total.percent);
+
+ this.element
+ .find('.plupload_total_status')
+ .html(up.total.percent + '%')
+ .end()
+ .find('.plupload_total_file_size')
+ .html(plupload.formatSize(up.total.size))
+ .end()
+ .find('.plupload_upload_status')
+ .html(_('Uploaded %d/%d files').replace('%d/%d', up.total.uploaded+'/'+up.files.length));
+ },
+
+
+ _updateFileList: function() {
+ var self = this, up = this.uploader, filelist = this.filelist,
+ count = 0,
+ id, prefix = this.id + '_',
+ fields;
+
+ // destroy sortable if enabled
+ if ($.ui.sortable && this.options.sortable) {
+ $('tbody.ui-sortable', filelist).sortable('destroy');
+ }
+
+ filelist.empty();
+
+ $.each(up.files, function(i, file) {
+ fields = '';
+ id = prefix + count;
+
+ if (file.status === plupload.DONE) {
+ if (file.target_name) {
+ fields += '<input type="hidden" name="' + id + '_tmpname" value="'+plupload.xmlEncode(file.target_name)+'" />';
+ }
+ fields += '<input type="hidden" name="' + id + '_name" value="'+plupload.xmlEncode(file.name)+'" />';
+ fields += '<input type="hidden" name="' + id + '_status" value="' + (file.status === plupload.DONE ? 'done' : 'failed') + '" />';
+
+ count++;
+ self.counter.val(count);
+ }
+
+ filelist.append(
+ '<tr class="ui-state-default plupload_file" id="' + file.id + '">' +
+ '<td class="plupload_cell plupload_file_name"><span>' + file.name + '</span></td>' +
+ '<td class="plupload_cell plupload_file_status">' + file.percent + '%</td>' +
+ '<td class="plupload_cell plupload_file_size">' + plupload.formatSize(file.size) + '</td>' +
+ '<td class="plupload_cell plupload_file_action"><div class="ui-icon"></div>' + fields + '</td>' +
+ '</tr>'
+ );
+
+ self._handleFileStatus(file);
+
+ $('#' + file.id + '.plupload_delete .ui-icon, #' + file.id + '.plupload_done .ui-icon')
+ .click(function(e) {
+ $('#' + file.id).remove();
+ up.removeFile(file);
+
+ e.preventDefault();
+ });
+
+ self._trigger('updatelist', null, filelist);
+ });
+
+ if (up.total.queued === 0) {
+ $('.ui-button-text', self.browse_button).html(_('Add Files'));
+ } else {
+ $('.ui-button-text', self.browse_button).html(_('%d files queued').replace('%d', up.total.queued));
+ }
+
+
+ if (up.files.length === (up.total.uploaded + up.total.failed)) {
+ self.start_button.button('disable');
+ } else {
+ self.start_button.button('enable');
+ }
+
+
+ // Scroll to end of file list
+ filelist[0].scrollTop = filelist[0].scrollHeight;
+
+ self._updateTotalProgress();
+
+ if (!up.files.length && up.features.dragdrop && up.settings.dragdrop) {
+ // Re-add drag message if there are no files
+ $('#' + id + '_filelist').append('<tr><td class="plupload_droptext">' + _("Drag files here.") + '</td></tr>');
+ } else {
+ // Otherwise re-initialize sortable
+ if (self.options.sortable && $.ui.sortable) {
+ self._enableSortingList();
+ }
+ }
+ },
+
+
+ _enableRenaming: function() {
+ var self = this;
+
+ this.filelist.on('click', '.plupload_delete .plupload_file_name span', function(e) {
+ var targetSpan = $(e.target), file, parts, name, ext = "";
+
+ // Get file name and split out name and extension
+ file = self.uploader.getFile(targetSpan.parents('tr')[0].id);
+ name = file.name;
+ parts = /^(.+)(\.[^.]+)$/.exec(name);
+ if (parts) {
+ name = parts[1];
+ ext = parts[2];
+ }
+
+ // Display input element
+ targetSpan.hide().after('<input class="plupload_file_rename" type="text" />');
+ targetSpan.next().val(name).focus().blur(function() {
+ targetSpan.show().next().remove();
+ }).keydown(function(e) {
+ var targetInput = $(this);
+
+ if ($.inArray(e.keyCode, [13, 27]) !== -1) {
+ e.preventDefault();
+
+ // Rename file and glue extension back on
+ if (e.keyCode === 13) {
+ file.name = targetInput.val() + ext;
+ targetSpan.html(file.name);
+ }
+ targetInput.blur();
+ }
+ });
+ });
+ },
+
+
+ _enableDragAndDrop: function() {
+ this.filelist.append('<tr><td class="plupload_droptext">' + _("Drag files here.") + '</td></tr>');
+
+ this.filelist.parent().attr('id', this.id + '_dropbox');
+
+ this.uploader.settings.drop_element = this.options.drop_element = this.id + '_dropbox';
+ },
+
+
+ _enableSortingList: function() {
+ var idxStart, self = this;
+
+ if ($('tbody tr', this.filelist).length < 2) {
+ return;
+ }
+
+ $('tbody', this.filelist).sortable({
+ containment: 'parent',
+ items: '.plupload_delete',
+
+ helper: function(e, el) {
+ return el.clone(true).find('td:not(.plupload_file_name)').remove().end().css('width', '100%');
+ },
+
+ stop: function(e, ui) {
+ var i, length, idx, files = [];
+
+ $.each($(this).sortable('toArray'), function(i, id) {
+ files[files.length] = self.uploader.getFile(id);
+ });
+
+ files.unshift(files.length);
+ files.unshift(0);
+
+ // re-populate files array
+ Array.prototype.splice.apply(self.uploader.files, files);
+ }
+ });
+ },
+
+ notify: function(type, message) {
+ var popup = $(
+ '<div class="plupload_message">' +
+ '<span class="plupload_message_close ui-icon ui-icon-circle-close" title="'+_('Close')+'"></span>' +
+ '<p><span class="ui-icon"></span>' + message + '</p>' +
+ '</div>'
+ );
+
+ popup
+ .addClass('ui-state-' + (type === 'error' ? 'error' : 'highlight'))
+ .find('p .ui-icon')
+ .addClass('ui-icon-' + (type === 'error' ? 'alert' : 'info'))
+ .end()
+ .find('.plupload_message_close')
+ .click(function() {
+ popup.remove();
+ })
+ .end();
+
+ $('.plupload_header_content', this.container).append(popup);
+ },
+
+
+
+ destroy: function() {
+ // unbind all button events
+ $('.plupload_button', this.element).unbind();
+
+ // destroy buttons
+ if ($.ui.button) {
+ $('.plupload_add, .plupload_start, .plupload_stop', this.container)
+ .button('destroy');
+ }
+
+ // destroy progressbar
+ if ($.ui.progressbar) {
+ this.progressbar.progressbar('destroy');
+ }
+
+ // destroy sortable behavior
+ if ($.ui.sortable && this.options.sortable) {
+ $('tbody', this.filelist).sortable('destroy');
+ }
+
+ // destroy uploader instance
+ this.uploader.destroy();
+
+ // restore the elements initial state
+ this.element
+ .empty()
+ .html(this.contents_bak);
+ this.contents_bak = '';
+
+ $.Widget.prototype.destroy.apply(this);
+ }
+});
+
+
+} (window, document, plupload, jQuery));
diff --git a/debian/missing-sources/plupload/javascript/plupload.browserplus.js b/debian/missing-sources/plupload/javascript/plupload.browserplus.js
new file mode 100644
index 0000000..1a06b79
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/plupload.browserplus.js
@@ -0,0 +1,361 @@
+/**
+ * plupload.browserplus.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global plupload:false, BrowserPlus:false, window:false */
+
+(function(plupload) {
+ /**
+ * Yahoo BrowserPlus implementation. This runtime supports these features: dragdrop, jpgresize, pngresize.
+ *
+ * @static
+ * @class plupload.runtimes.BrowserPlus
+ * @extends plupload.Runtime
+ */
+ plupload.runtimes.BrowserPlus = plupload.addRuntime("browserplus", {
+ /**
+ * Returns a list of supported features for the runtime.
+ *
+ * @return {Object} Name/value object with supported features.
+ */
+ getFeatures : function() {
+ return {
+ dragdrop : true,
+ jpgresize : true,
+ pngresize : true,
+ chunks : true,
+ progress: true,
+ multipart: true,
+ multi_selection: true
+ };
+ },
+
+ /**
+ * Initializes the browserplus runtime.
+ *
+ * @method init
+ * @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
+ * @param {function} callback Callback to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
+ */
+ init : function(uploader, callback) {
+ var browserPlus = window.BrowserPlus, browserPlusFiles = {}, settings = uploader.settings, resize = settings.resize;
+
+ function addSelectedFiles(native_files) {
+ var files, i, selectedFiles = [], file, id;
+
+ // Add the native files and setup plupload files
+ for (i = 0; i < native_files.length; i++) {
+ file = native_files[i];
+ id = plupload.guid();
+ browserPlusFiles[id] = file;
+
+ selectedFiles.push(new plupload.File(id, file.name, file.size));
+ }
+
+ // Any files selected fire event
+ if (i) {
+ uploader.trigger("FilesAdded", selectedFiles);
+ }
+ }
+
+ // Setup event listeners if browserplus was initialized
+ function setup() {
+ var disabled = false;
+
+ // Add drop handler
+ uploader.bind("PostInit", function() {
+ var dropTargetElm, dropElmId = settings.drop_element,
+ dropTargetId = uploader.id + '_droptarget',
+ dropElm = document.getElementById(dropElmId),
+ lastState;
+
+ // Enable/disable drop support for the drop target
+ // this is needed to resolve IE bubbeling issues and make it possible to drag/drop
+ // files into gears runtimes on the same page
+ function addDropHandler(id, end_callback) {
+ // Add drop target and listener
+ browserPlus.DragAndDrop.AddDropTarget({id : id}, function(res) {
+ browserPlus.DragAndDrop.AttachCallbacks({
+ id : id,
+ hover : function(res) {
+ if (!res && end_callback) {
+ end_callback();
+ }
+ },
+ drop : function(res) {
+ if (end_callback) {
+ end_callback();
+ }
+
+ addSelectedFiles(res);
+ }
+ }, function() {
+ });
+ });
+ }
+
+ function hide() {
+ document.getElementById(dropTargetId).style.top = '-1000px';
+ }
+
+ if (dropElm) {
+ // Since IE has issues with bubbeling when it comes to the drop of files
+ // we need to do this hack where we show a drop target div element while dropping
+ if (document.attachEvent && (/MSIE/gi).test(navigator.userAgent)) {
+ // Create drop target
+ dropTargetElm = document.createElement('div');
+ dropTargetElm.setAttribute('id', dropTargetId);
+ plupload.extend(dropTargetElm.style, {
+ position : 'absolute',
+ top : '-1000px',
+ background : 'red',
+ filter : 'alpha(opacity=0)',
+ opacity : 0
+ });
+
+ document.body.appendChild(dropTargetElm);
+
+ plupload.addEvent(dropElm, 'dragenter', function(e) {
+ var dropElm, dropElmPos;
+
+ dropElm = document.getElementById(dropElmId);
+ dropElmPos = plupload.getPos(dropElm);
+
+ plupload.extend(document.getElementById(dropTargetId).style, {
+ top : dropElmPos.y + 'px',
+ left : dropElmPos.x + 'px',
+ width : dropElm.offsetWidth + 'px',
+ height : dropElm.offsetHeight + 'px'
+ });
+ });
+
+ addDropHandler(dropTargetId, hide);
+ } else {
+ addDropHandler(dropElmId);
+ }
+ }
+
+ plupload.addEvent(document.getElementById(settings.browse_button), 'click', function(e) {
+ var mimes = [], i, a, filters = settings.filters, ext, type;
+
+ e.preventDefault();
+
+ if (disabled) {
+ return;
+ }
+
+ // Convert extensions to mimetypes
+ no_type_restriction:
+ for (i = 0; i < filters.length; i++) {
+ ext = filters[i].extensions.split(',');
+
+ for (a = 0; a < ext.length; a++) {
+ if (ext[a] === '*') {
+ mimes = [];
+ break no_type_restriction;
+ }
+ type = plupload.mimeTypes[ext[a]];
+
+ if (type && plupload.inArray(type, mimes) === -1) {
+ mimes.push(plupload.mimeTypes[ext[a]]);
+ }
+ }
+ }
+
+ browserPlus.FileBrowse.OpenBrowseDialog({
+ mimeTypes : mimes
+ }, function(res) {
+ if (res.success) {
+ addSelectedFiles(res.value);
+ }
+ });
+ });
+
+ // Prevent IE leaks
+ dropElm = dropTargetElm = null;
+ });
+
+ uploader.bind("CancelUpload", function() {
+ browserPlus.Uploader.cancel({}, function(){});
+ });
+
+ uploader.bind("DisableBrowse", function(up, state) {
+ disabled = state;
+ });
+
+ uploader.bind("UploadFile", function(up, file) {
+ var nativeFile = browserPlusFiles[file.id], reqParams = {},
+ chunkSize = up.settings.chunk_size, loadProgress, chunkStack = [];
+
+ function uploadFile(chunk, chunks) {
+ var chunkFile;
+
+ // Stop upload if file is maked as failed
+ if (file.status == plupload.FAILED) {
+ return;
+ }
+
+ reqParams.name = file.target_name || file.name;
+
+ // Only send chunk parameters if chunk size is defined
+ if (chunkSize) {
+ reqParams.chunk = "" + chunk;
+ reqParams.chunks = "" + chunks;
+ }
+
+ chunkFile = chunkStack.shift();
+
+ browserPlus.Uploader.upload({
+ url : up.settings.url,
+ files : {file : chunkFile},
+ cookies : document.cookies,
+ postvars : plupload.extend(reqParams, up.settings.multipart_params),
+ progressCallback : function(res) {
+ var i, loaded = 0;
+
+ // since more than 1 chunk can be sent at a time, keep track of how many bytes
+ // of each chunk was sent
+ loadProgress[chunk] = parseInt(res.filePercent * chunkFile.size / 100, 10);
+ for (i = 0; i < loadProgress.length; i++) {
+ loaded += loadProgress[i];
+ }
+
+ file.loaded = loaded;
+ up.trigger('UploadProgress', file);
+ }
+ }, function(res) {
+ var httpStatus, chunkArgs;
+
+ if (res.success) {
+ httpStatus = res.value.statusCode;
+
+ if (chunkSize) {
+ up.trigger('ChunkUploaded', file, {
+ chunk : chunk,
+ chunks : chunks,
+ response : res.value.body,
+ status : httpStatus
+ });
+ }
+
+ if (chunkStack.length > 0) {
+ // More chunks to be uploaded
+ uploadFile(++chunk, chunks);
+ } else {
+ file.status = plupload.DONE;
+
+ up.trigger('FileUploaded', file, {
+ response : res.value.body,
+ status : httpStatus
+ });
+
+ // Is error status
+ if (httpStatus >= 400) {
+ up.trigger('Error', {
+ code : plupload.HTTP_ERROR,
+ message : plupload.translate('HTTP Error.'),
+ file : file,
+ status : httpStatus
+ });
+ }
+ }
+ } else {
+ up.trigger('Error', {
+ code : plupload.GENERIC_ERROR,
+ message : plupload.translate('Generic Error.'),
+ file : file,
+ details : res.error
+ });
+ }
+ });
+ }
+
+ function chunkAndUploadFile(native_file) {
+ file.size = native_file.size;
+ if (chunkSize) {
+ browserPlus.FileAccess.chunk({file : native_file, chunkSize : chunkSize}, function(cr) {
+ if (cr.success) {
+ var chunks = cr.value, len = chunks.length;
+
+ loadProgress = Array(len);
+
+ for (var i = 0; i < len; i++) {
+ loadProgress[i] = 0;
+ chunkStack.push(chunks[i]);
+ }
+
+ uploadFile(0, len);
+ }
+ });
+ } else {
+ loadProgress = Array(1);
+ chunkStack.push(native_file);
+ uploadFile(0, 1);
+ }
+ }
+
+ // Resize image if it's a supported format and resize is enabled
+ if (resize && /\.(png|jpg|jpeg)$/i.test(file.name)) {
+ BrowserPlus.ImageAlter.transform({
+ file : nativeFile,
+ quality : resize.quality || 90,
+ actions : [{
+ scale : {
+ maxwidth : resize.width,
+ maxheight : resize.height
+ }
+ }]
+ }, function(res) {
+ if (res.success) {
+ chunkAndUploadFile(res.value.file);
+ }
+ });
+ } else {
+ chunkAndUploadFile(nativeFile);
+ }
+ });
+
+ callback({success : true});
+ }
+
+ // Check for browserplus object
+ if (browserPlus) {
+ browserPlus.init(function(res) {
+ var services = [
+ {service: "Uploader", version: "3"},
+ {service: "DragAndDrop", version: "1"},
+ {service: "FileBrowse", version: "1"},
+ {service: "FileAccess", version: "2"}
+ ];
+
+ if (resize) {
+ services.push({service : 'ImageAlter', version : "4"});
+ }
+
+ if (res.success) {
+ browserPlus.require({
+ services : services
+ }, function(sres) {
+ if (sres.success) {
+ setup();
+ } else {
+ callback();
+ }
+ });
+ } else {
+ callback();
+ }
+ });
+ } else {
+ callback();
+ }
+ }
+ });
+})(plupload);
diff --git a/debian/missing-sources/plupload/javascript/plupload.flash.js b/debian/missing-sources/plupload/javascript/plupload.flash.js
new file mode 100644
index 0000000..7caa511
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/plupload.flash.js
@@ -0,0 +1,431 @@
+/**
+ * plupload.flash.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global window:false, document:false, plupload:false, ActiveXObject:false, escape:false */
+
+(function(window, document, plupload, undef) {
+ var uploadInstances = {}, initialized = {};
+
+ function getFlashVersion() {
+ var version;
+
+ try {
+ version = navigator.plugins['Shockwave Flash'];
+ version = version.description;
+ } catch (e1) {
+ try {
+ version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
+ } catch (e2) {
+ version = '0.0';
+ }
+ }
+
+ version = version.match(/\d+/g);
+
+ return parseFloat(version[0] + '.' + version[1]);
+ }
+
+ plupload.flash = {
+ /**
+ * Will be executed by the Flash runtime when it sends out events.
+ *
+ * @param {String} id If for the upload instance.
+ * @param {String} name Event name to trigger.
+ * @param {Object} obj Parameters to be passed with event.
+ */
+ trigger : function(id, name, obj) {
+
+ // Detach the call so that error handling in the browser is presented correctly
+ setTimeout(function() {
+ var uploader = uploadInstances[id], i, args;
+
+ if (uploader) {
+ uploader.trigger('Flash:' + name, obj);
+ }
+ }, 0);
+ }
+ };
+
+ /**
+ * FlashRuntime implementation. This runtime supports these features: jpgresize, pngresize, chunks.
+ *
+ * @static
+ * @class plupload.runtimes.Flash
+ * @extends plupload.Runtime
+ */
+ plupload.runtimes.Flash = plupload.addRuntime("flash", {
+
+ /**
+ * Returns a list of supported features for the runtime.
+ *
+ * @return {Object} Name/value object with supported features.
+ */
+ getFeatures : function() {
+ return {
+ jpgresize: true,
+ pngresize: true,
+ maxWidth: 8091,
+ maxHeight: 8091,
+ chunks: true,
+ progress: true,
+ multipart: true,
+ multi_selection: true
+ };
+ },
+
+ /**
+ * Initializes the upload runtime. This method should add necessary items to the DOM and register events needed for operation.
+ *
+ * @method init
+ * @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
+ * @param {function} callback Callback to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
+ */
+ init : function(uploader, callback) {
+ var browseButton, flashContainer, waitCount = 0, container = document.body;
+
+ if (getFlashVersion() < 10) {
+ callback({success : false});
+ return;
+ }
+
+ initialized[uploader.id] = false;
+ uploadInstances[uploader.id] = uploader;
+
+ // Find browse button and set to to be relative
+ browseButton = document.getElementById(uploader.settings.browse_button);
+
+ // Create flash container and insert it at an absolute position within the browse button
+ flashContainer = document.createElement('div');
+ flashContainer.id = uploader.id + '_flash_container';
+
+ plupload.extend(flashContainer.style, {
+ position : 'absolute',
+ top : '0px',
+ background : uploader.settings.shim_bgcolor || 'transparent',
+ zIndex : 99999,
+ width : '100%',
+ height : '100%'
+ });
+
+ flashContainer.className = 'plupload flash';
+
+ if (uploader.settings.container) {
+ container = document.getElementById(uploader.settings.container);
+ if (plupload.getStyle(container, 'position') === 'static') {
+ container.style.position = 'relative';
+ }
+ }
+
+ container.appendChild(flashContainer);
+
+ // insert flash object
+ (function() {
+ var html, el;
+
+ html = '<object id="' + uploader.id + '_flash" type="application/x-shockwave-flash" data="' + uploader.settings.flash_swf_url + '" ';
+
+ if (plupload.ua.ie) {
+ html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
+ }
+
+ html += 'width="100%" height="100%" style="outline:0">' +
+ '<param name="movie" value="' + uploader.settings.flash_swf_url + '" />' +
+ '<param name="flashvars" value="id=' + escape(uploader.id) + '" />' +
+ '<param name="wmode" value="transparent" />' +
+ '<param name="allowscriptaccess" value="always" />' +
+ '</object>';
+
+ if (plupload.ua.ie) {
+ el = document.createElement('div');
+ flashContainer.appendChild(el);
+ el.outerHTML = html;
+ el = null; // just in case
+ } else {
+ flashContainer.innerHTML = html;
+ }
+ }());
+
+ function getFlashObj() {
+ return document.getElementById(uploader.id + '_flash');
+ }
+
+ function waitLoad() {
+
+ // Wait for 5 sec
+ if (waitCount++ > 5000) {
+ callback({success : false});
+ return;
+ }
+
+ if (initialized[uploader.id] === false) { // might also be undefined, if uploader was destroyed by that moment
+ setTimeout(waitLoad, 1);
+ }
+ }
+
+ waitLoad();
+
+ // Fix IE memory leaks
+ browseButton = flashContainer = null;
+
+ // destroy should always be available, after Flash:Init or before (#516)
+ uploader.bind("Destroy", function(up) {
+ var flashContainer;
+
+ plupload.removeAllEvents(document.body, up.id);
+
+ delete initialized[up.id];
+ delete uploadInstances[up.id];
+
+ flashContainer = document.getElementById(up.id + '_flash_container');
+ if (flashContainer) {
+ flashContainer.parentNode.removeChild(flashContainer);
+ }
+ });
+
+ // Wait for Flash to send init event
+ uploader.bind("Flash:Init", function() {
+ var lookup = {}, i;
+
+ try {
+ getFlashObj().setFileFilters(uploader.settings.filters, uploader.settings.multi_selection);
+ } catch (ex) {
+ callback({success : false});
+ return;
+ }
+
+ // Prevent eventual reinitialization of the instance
+ if (initialized[uploader.id]) {
+ return;
+ }
+ initialized[uploader.id] = true;
+
+ uploader.bind("UploadFile", function(up, file) {
+ var settings = up.settings, resize = uploader.settings.resize || {};
+
+ getFlashObj().uploadFile(lookup[file.id], settings.url, {
+ name : file.target_name || file.name,
+ mime : plupload.mimeTypes[file.name.replace(/^.+\.([^.]+)/, '$1').toLowerCase()] || 'application/octet-stream',
+ chunk_size : settings.chunk_size,
+ width : resize.width,
+ height : resize.height,
+ quality : resize.quality,
+ multipart : settings.multipart,
+ multipart_params : settings.multipart_params || {},
+ file_data_name : settings.file_data_name,
+ format : /\.(jpg|jpeg)$/i.test(file.name) ? 'jpg' : 'png',
+ headers : settings.headers,
+ urlstream_upload : settings.urlstream_upload
+ });
+ });
+
+ uploader.bind("CancelUpload", function() {
+ getFlashObj().cancelUpload();
+ });
+
+
+ uploader.bind("Flash:UploadProcess", function(up, flash_file) {
+ var file = up.getFile(lookup[flash_file.id]);
+
+ if (file.status != plupload.FAILED) {
+ file.loaded = flash_file.loaded;
+ file.size = flash_file.size;
+
+ up.trigger('UploadProgress', file);
+ }
+ });
+
+ uploader.bind("Flash:UploadChunkComplete", function(up, info) {
+ var chunkArgs, file = up.getFile(lookup[info.id]);
+
+ chunkArgs = {
+ chunk : info.chunk,
+ chunks : info.chunks,
+ response : info.text
+ };
+
+ up.trigger('ChunkUploaded', file, chunkArgs);
+
+ // Stop upload if file is maked as failed
+ if (file.status !== plupload.FAILED && up.state !== plupload.STOPPED) {
+ getFlashObj().uploadNextChunk();
+ }
+
+ // Last chunk then dispatch FileUploaded event
+ if (info.chunk == info.chunks - 1) {
+ file.status = plupload.DONE;
+
+ up.trigger('FileUploaded', file, {
+ response : info.text
+ });
+ }
+ });
+
+ uploader.bind("Flash:SelectFiles", function(up, selected_files) {
+ var file, i, files = [], id;
+
+ // Add the selected files to the file queue
+ for (i = 0; i < selected_files.length; i++) {
+ file = selected_files[i];
+
+ // Store away flash ref internally
+ id = plupload.guid();
+ lookup[id] = file.id;
+ lookup[file.id] = id;
+
+ files.push(new plupload.File(id, file.name, file.size));
+ }
+
+ // Trigger FilesAdded event if we added any
+ if (files.length) {
+ uploader.trigger("FilesAdded", files);
+ }
+ });
+
+ uploader.bind("Flash:SecurityError", function(up, err) {
+ uploader.trigger('Error', {
+ code : plupload.SECURITY_ERROR,
+ message : plupload.translate('Security error.'),
+ details : err.message,
+ file : uploader.getFile(lookup[err.id])
+ });
+ });
+
+ uploader.bind("Flash:GenericError", function(up, err) {
+ uploader.trigger('Error', {
+ code : plupload.GENERIC_ERROR,
+ message : plupload.translate('Generic error.'),
+ details : err.message,
+ file : uploader.getFile(lookup[err.id])
+ });
+ });
+
+ uploader.bind("Flash:IOError", function(up, err) {
+ uploader.trigger('Error', {
+ code : plupload.IO_ERROR,
+ message : plupload.translate('IO error.'),
+ details : err.message,
+ file : uploader.getFile(lookup[err.id])
+ });
+ });
+
+ uploader.bind("Flash:ImageError", function(up, err) {
+ uploader.trigger('Error', {
+ code : parseInt(err.code, 10),
+ message : plupload.translate('Image error.'),
+ file : uploader.getFile(lookup[err.id])
+ });
+ });
+
+ uploader.bind('Flash:StageEvent:rollOver', function(up) {
+ var browseButton, hoverClass;
+
+ browseButton = document.getElementById(uploader.settings.browse_button);
+ hoverClass = up.settings.browse_button_hover;
+
+ if (browseButton && hoverClass) {
+ plupload.addClass(browseButton, hoverClass);
+ }
+ });
+
+ uploader.bind('Flash:StageEvent:rollOut', function(up) {
+ var browseButton, hoverClass;
+
+ browseButton = document.getElementById(uploader.settings.browse_button);
+ hoverClass = up.settings.browse_button_hover;
+
+ if (browseButton && hoverClass) {
+ plupload.removeClass(browseButton, hoverClass);
+ }
+ });
+
+ uploader.bind('Flash:StageEvent:mouseDown', function(up) {
+ var browseButton, activeClass;
+
+ browseButton = document.getElementById(uploader.settings.browse_button);
+ activeClass = up.settings.browse_button_active;
+
+ if (browseButton && activeClass) {
+ plupload.addClass(browseButton, activeClass);
+
+ // Make sure that browse_button has active state removed from it
+ plupload.addEvent(document.body, 'mouseup', function() {
+ plupload.removeClass(browseButton, activeClass);
+ }, up.id);
+ }
+ });
+
+ uploader.bind('Flash:StageEvent:mouseUp', function(up) {
+ var browseButton, activeClass;
+
+ browseButton = document.getElementById(uploader.settings.browse_button);
+ activeClass = up.settings.browse_button_active;
+
+ if (browseButton && activeClass) {
+ plupload.removeClass(browseButton, activeClass);
+ }
+ });
+
+
+ uploader.bind('Flash:ExifData', function(up, obj) {
+ uploader.trigger('ExifData', uploader.getFile(lookup[obj.id]), obj.data);
+ });
+
+
+ uploader.bind('Flash:GpsData', function(up, obj) {
+ uploader.trigger('GpsData', uploader.getFile(lookup[obj.id]), obj.data);
+ });
+
+
+ uploader.bind("QueueChanged", function(up) {
+ uploader.refresh();
+ });
+
+ uploader.bind("FilesRemoved", function(up, files) {
+ var i;
+
+ for (i = 0; i < files.length; i++) {
+ getFlashObj().removeFile(lookup[files[i].id]);
+ }
+ });
+
+ uploader.bind("StateChanged", function(up) {
+ uploader.refresh();
+ });
+
+ uploader.bind("Refresh", function(up) {
+ var browseButton, browsePos, browseSize;
+
+ // Set file filters incase it has been changed dynamically
+ getFlashObj().setFileFilters(uploader.settings.filters, uploader.settings.multi_selection);
+
+ browseButton = document.getElementById(up.settings.browse_button);
+ if (browseButton) {
+ browsePos = plupload.getPos(browseButton, document.getElementById(up.settings.container));
+ browseSize = plupload.getSize(browseButton);
+
+ plupload.extend(document.getElementById(up.id + '_flash_container').style, {
+ top : browsePos.y + 'px',
+ left : browsePos.x + 'px',
+ width : browseSize.w + 'px',
+ height : browseSize.h + 'px'
+ });
+ }
+ });
+
+ uploader.bind("DisableBrowse", function(up, disabled) {
+ getFlashObj().disableBrowse(disabled);
+ });
+
+ callback({success : true});
+ });
+ }
+ });
+})(window, document, plupload);
diff --git a/debian/missing-sources/plupload/javascript/plupload.gears.js b/debian/missing-sources/plupload/javascript/plupload.gears.js
new file mode 100644
index 0000000..c18a828
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/plupload.gears.js
@@ -0,0 +1,446 @@
+/**
+ * plupload.gears.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global window:false, document:false, plupload:false, google:false, GearsFactory:false, ActiveXObject:false */
+
+// Copyright 2007, Google Inc.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// 3. Neither the name of Google Inc. nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Sets up google.gears.*, which is *the only* supported way to access Gears.
+//
+// Circumvent this file at your own risk!
+//
+// In the future, Gears may automatically define google.gears.* without this
+// file. Gears may use these objects to transparently fix bugs and compatibility
+// issues. Applications that use the code below will continue to work seamlessly
+// when that happens.
+
+(function() {
+ // We are already defined. Hooray!
+ if (window.google && google.gears) {
+ return;
+ }
+
+ var factory = null;
+
+ // Firefox
+ if (typeof GearsFactory != 'undefined') {
+ factory = new GearsFactory();
+ } else {
+ // IE
+ try {
+ factory = new ActiveXObject('Gears.Factory');
+ // privateSetGlobalObject is only required and supported on WinCE.
+ if (factory.getBuildInfo().indexOf('ie_mobile') != -1) {
+ factory.privateSetGlobalObject(this);
+ }
+ } catch (e) {
+ // Safari
+ if ((typeof navigator.mimeTypes != 'undefined') && navigator.mimeTypes["application/x-googlegears"]) {
+ factory = document.createElement("object");
+ factory.style.display = "none";
+ factory.width = 0;
+ factory.height = 0;
+ factory.type = "application/x-googlegears";
+ document.documentElement.appendChild(factory);
+ }
+ }
+ }
+
+ // *Do not* define any objects if Gears is not installed. This mimics the
+ // behavior of Gears defining the objects in the future.
+ if (!factory) {
+ return;
+ }
+
+ // Now set up the objects, being careful not to overwrite anything.
+ //
+ // Note: In Internet Explorer for Windows Mobile, you can't add properties to
+ // the window object. However, global objects are automatically added as
+ // properties of the window object in all browsers.
+ if (!window.google) {
+ window.google = {};
+ }
+
+ if (!google.gears) {
+ google.gears = {factory: factory};
+ }
+})();
+
+(function(window, document, plupload, undef) {
+ var blobs = {};
+
+ function scaleImage(image_blob, resize, mime) {
+ var percentage, canvas, context, scale;
+
+ // Setup canvas and scale
+ canvas = google.gears.factory.create('beta.canvas');
+ try {
+ canvas.decode(image_blob);
+
+ if (!resize.width) {
+ resize.width = canvas.width;
+ }
+
+ if (!resize.height) {
+ resize.height = canvas.height;
+ }
+
+ scale = Math.min(resize.width / canvas.width, resize.height / canvas.height);
+
+ if (scale < 1) {
+ canvas.resize(Math.round(canvas.width * scale), Math.round(canvas.height * scale));
+ } else if (!resize.quality || mime !== 'image/jpeg') {
+ return image_blob;
+ }
+
+ if (resize.quality) {
+ return canvas.encode(mime, {quality : resize.quality / 100});
+ }
+
+ return canvas.encode(mime);
+ } catch (e) {
+ // Ignore for example when a user uploads a file that can't be decoded
+ }
+
+ return image_blob;
+ }
+
+ /**
+ * Gears implementation. This runtime supports these features: dragdrop, jpgresize, pngresize, chunks.
+ *
+ * @static
+ * @class plupload.runtimes.Gears
+ * @extends plupload.Runtime
+ */
+ plupload.runtimes.Gears = plupload.addRuntime("gears", {
+ /**
+ * Returns a list of supported features for the runtime.
+ *
+ * @return {Object} Name/value object with supported features.
+ */
+ getFeatures : function() {
+ return {
+ dragdrop: true,
+ jpgresize: true,
+ pngresize: true,
+ chunks: true,
+ progress: true,
+ multipart: true,
+ multi_selection: true
+ };
+ },
+
+ /**
+ * Initializes the upload runtime.
+ *
+ * @method init
+ * @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
+ * @param {function} callback Callback to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
+ */
+ init : function(uploader, callback) {
+ var desktop, req, disabled = false;
+
+ // Check for gears support
+ if (!window.google || !google.gears) {
+ return callback({success : false});
+ }
+
+ try {
+ desktop = google.gears.factory.create('beta.desktop');
+ } catch (e) {
+ // Might fail on the latest Gecko build for some odd reason
+ return callback({success : false});
+ }
+
+ function addSelectedFiles(selected_files) {
+ var file, i, files = [], id;
+
+ // Add the selected files to the file queue
+ for (i = 0; i < selected_files.length; i++) {
+ file = selected_files[i];
+
+ // Store away gears blob internally
+ id = plupload.guid();
+ blobs[id] = file.blob;
+
+ files.push(new plupload.File(id, file.name, file.blob.length));
+ }
+
+ // Fire FilesAdded event
+ uploader.trigger("FilesAdded", files);
+ }
+
+ // Add drop handler
+ uploader.bind("PostInit", function() {
+ var settings = uploader.settings, dropElm = document.getElementById(settings.drop_element);
+
+ if (dropElm) {
+ // Block browser default drag over
+ plupload.addEvent(dropElm, 'dragover', function(e) {
+ desktop.setDropEffect(e, 'copy');
+ e.preventDefault();
+ }, uploader.id);
+
+ // Attach drop handler and grab files from Gears
+ plupload.addEvent(dropElm, 'drop', function(e) {
+ var dragData = desktop.getDragData(e, 'application/x-gears-files');
+
+ if (dragData) {
+ addSelectedFiles(dragData.files);
+ }
+
+ e.preventDefault();
+ }, uploader.id);
+
+ // Prevent IE leak
+ dropElm = 0;
+ }
+
+ // Add browse button
+ plupload.addEvent(document.getElementById(settings.browse_button), 'click', function(e) {
+ var filters = [], i, a, ext;
+
+ e.preventDefault();
+
+ if (disabled) {
+ return;
+ }
+
+ no_type_restriction:
+ for (i = 0; i < settings.filters.length; i++) {
+ ext = settings.filters[i].extensions.split(',');
+
+ for (a = 0; a < ext.length; a++) {
+ if (ext[a] === '*') {
+ filters = [];
+ break no_type_restriction;
+ }
+
+ filters.push('.' + ext[a]);
+ }
+ }
+
+ desktop.openFiles(addSelectedFiles, {singleFile : !settings.multi_selection, filter : filters});
+ }, uploader.id);
+ });
+
+
+ uploader.bind("CancelUpload", function() {
+ if (req.abort) {
+ req.abort();
+ }
+ });
+
+
+ uploader.bind("UploadFile", function(up, file) {
+ var chunk = 0, chunks, chunkSize, loaded = 0, resize = up.settings.resize, chunking;
+
+ // If file is png or jpeg and resize is configured then resize it
+ if (resize && /\.(png|jpg|jpeg)$/i.test(file.name)) {
+ blobs[file.id] = scaleImage(blobs[file.id], resize, /\.png$/i.test(file.name) ? 'image/png' : 'image/jpeg');
+ }
+
+ file.size = blobs[file.id].length;
+
+ chunkSize = up.settings.chunk_size;
+ chunking = chunkSize > 0;
+ chunks = Math.ceil(file.size / chunkSize);
+
+ // If chunking is disabled then upload the whole file in one huge chunk
+ if (!chunking) {
+ chunkSize = file.size;
+ chunks = 1;
+ }
+
+ function uploadNextChunk() {
+ var curChunkSize, multipart = up.settings.multipart, multipartLength = 0, reqArgs = {name : file.target_name || file.name}, url = up.settings.url;
+
+ // Sends the binary blob multipart encoded or raw depending on config
+ function sendBinaryBlob(blob) {
+ var builder, boundary = '----pluploadboundary' + plupload.guid(), dashdash = '--', crlf = '\r\n', multipartBlob, mimeType;
+
+ // Build multipart request
+ if (multipart) {
+ req.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
+ builder = google.gears.factory.create('beta.blobbuilder');
+
+ // Append mutlipart parameters
+ plupload.each(plupload.extend(reqArgs, up.settings.multipart_params), function(value, name) {
+ builder.append(
+ dashdash + boundary + crlf +
+ 'Content-Disposition: form-data; name="' + name + '"' + crlf + crlf
+ );
+
+ builder.append(value + crlf);
+ });
+
+ mimeType = plupload.mimeTypes[file.name.replace(/^.+\.([^.]+)/, '$1').toLowerCase()] || 'application/octet-stream';
+
+ // Add file header
+ builder.append(
+ dashdash + boundary + crlf +
+ 'Content-Disposition: form-data; name="' + up.settings.file_data_name + '"; filename="' + file.name + '"' + crlf +
+ 'Content-Type: ' + mimeType + crlf + crlf
+ );
+
+ // Add file data
+ builder.append(blob);
+
+ // Add footer
+ builder.append(crlf + dashdash + boundary + dashdash + crlf);
+ multipartBlob = builder.getAsBlob();
+ multipartLength = multipartBlob.length - blob.length;
+ blob = multipartBlob;
+ }
+
+ // Send blob or multipart blob depending on config
+ req.send(blob);
+ }
+
+ // File upload finished
+ if (file.status == plupload.DONE || file.status == plupload.FAILED || up.state == plupload.STOPPED) {
+ return;
+ }
+
+ // Only add chunking args if needed
+ if (chunking) {
+ reqArgs.chunk = chunk;
+ reqArgs.chunks = chunks;
+ }
+
+ // Setup current chunk size
+ curChunkSize = Math.min(chunkSize, file.size - (chunk * chunkSize));
+
+ if (!multipart) {
+ url = plupload.buildUrl(up.settings.url, reqArgs);
+ }
+
+ req = google.gears.factory.create('beta.httprequest');
+ req.open('POST', url);
+
+ // Add disposition and type if multipart is disabled
+ if (!multipart) {
+ req.setRequestHeader('Content-Disposition', 'attachment; filename="' + file.name + '"');
+ req.setRequestHeader('Content-Type', 'application/octet-stream');
+ }
+
+ // Set custom headers
+ plupload.each(up.settings.headers, function(value, name) {
+ req.setRequestHeader(name, value);
+ });
+
+ req.upload.onprogress = function(progress) {
+ file.loaded = loaded + progress.loaded - multipartLength;
+ up.trigger('UploadProgress', file);
+ };
+
+ req.onreadystatechange = function() {
+ var chunkArgs;
+
+ if (req.readyState == 4 && up.state !== plupload.STOPPED) {
+ if (req.status == 200) {
+ chunkArgs = {
+ chunk : chunk,
+ chunks : chunks,
+ response : req.responseText,
+ status : req.status
+ };
+
+ up.trigger('ChunkUploaded', file, chunkArgs);
+
+ // Stop upload
+ if (chunkArgs.cancelled) {
+ file.status = plupload.FAILED;
+ return;
+ }
+
+ loaded += curChunkSize;
+
+ if (++chunk >= chunks) {
+ file.status = plupload.DONE;
+ up.trigger('FileUploaded', file, {
+ response : req.responseText,
+ status : req.status
+ });
+ } else {
+ uploadNextChunk();
+ }
+ } else {
+ up.trigger('Error', {
+ code : plupload.HTTP_ERROR,
+ message : plupload.translate('HTTP Error.'),
+ file : file,
+ chunk : chunk,
+ chunks : chunks,
+ status : req.status
+ });
+ }
+ }
+ };
+
+ if (chunk < chunks) {
+ sendBinaryBlob(blobs[file.id].slice(chunk * chunkSize, curChunkSize));
+ }
+ }
+
+ // Start uploading chunks
+ uploadNextChunk();
+ });
+
+ uploader.bind("DisableBrowse", function(up, state) {
+ disabled = state;
+ });
+
+
+ uploader.bind("Destroy", function(up) {
+ var name, element,
+ elements = {
+ browseButton: up.settings.browse_button,
+ dropElm: up.settings.drop_element
+ };
+
+ // Unbind event handlers
+ for (name in elements) {
+ element = document.getElementById(elements[name]);
+ if (element) {
+ plupload.removeAllEvents(element, up.id);
+ }
+ }
+ });
+
+
+ callback({success : true});
+ }
+ });
+})(window, document, plupload);
diff --git a/debian/missing-sources/plupload/javascript/plupload.html4.js b/debian/missing-sources/plupload/javascript/plupload.html4.js
new file mode 100644
index 0000000..f3d7846
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/plupload.html4.js
@@ -0,0 +1,430 @@
+/**
+ * plupload.html4.js
+ *
+ * Copyright 2010, Ryan Demmer
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global plupload:false, window:false */
+
+(function(window, document, plupload, undef) {
+ function getById(id) {
+ return document.getElementById(id);
+ }
+
+ /**
+ * HTML4 implementation. This runtime has no special features it uses an form that posts files into an hidden iframe.
+ *
+ * @static
+ * @class plupload.runtimes.Html4
+ * @extends plupload.Runtime
+ */
+ plupload.runtimes.Html4 = plupload.addRuntime("html4", {
+ /**
+ * Returns a list of supported features for the runtime.
+ *
+ * @return {Object} Name/value object with supported features.
+ */
+ getFeatures : function() {
+ // Only multipart feature
+ return {
+ multipart: true,
+
+ // WebKit and Gecko 2+ can trigger file dialog progrmmatically
+ triggerDialog: (plupload.ua.gecko && window.FormData || plupload.ua.webkit)
+ };
+ },
+
+ /**
+ * Initializes the upload runtime.
+ *
+ * @method init
+ * @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
+ * @param {function} callback Callback to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
+ */
+ init : function(uploader, callback) {
+ uploader.bind("Init", function(up) {
+ var container = document.body, iframe, url = "javascript", currentFile,
+ input, currentFileId, fileIds = [], IE = /MSIE/.test(navigator.userAgent), mimes = [],
+ filters = up.settings.filters, i, ext, type, y;
+
+ // Convert extensions to mime types list
+ no_type_restriction:
+ for (i = 0; i < filters.length; i++) {
+ ext = filters[i].extensions.split(/,/);
+
+ for (y = 0; y < ext.length; y++) {
+
+ // If there's an asterisk in the list, then accept attribute is not required
+ if (ext[y] === '*') {
+ mimes = [];
+ break no_type_restriction;
+ }
+
+ type = plupload.mimeTypes[ext[y]];
+
+ if (type && plupload.inArray(type, mimes) === -1) {
+ mimes.push(type);
+ }
+ }
+ }
+
+ mimes = mimes.join(',');
+
+ function createForm() {
+ var form, input, bgcolor, browseButton;
+
+ // Setup unique id for form
+ currentFileId = plupload.guid();
+
+ // Save id for Destroy handler
+ fileIds.push(currentFileId);
+
+ // Create form
+ form = document.createElement('form');
+ form.setAttribute('id', 'form_' + currentFileId);
+ form.setAttribute('method', 'post');
+ form.setAttribute('enctype', 'multipart/form-data');
+ form.setAttribute('encoding', 'multipart/form-data');
+ form.setAttribute("target", up.id + '_iframe');
+ form.style.position = 'absolute';
+
+ // Create input and set attributes
+ input = document.createElement('input');
+ input.setAttribute('id', 'input_' + currentFileId);
+ input.setAttribute('type', 'file');
+ input.setAttribute('accept', mimes);
+ input.setAttribute('size', 1);
+
+ browseButton = getById(up.settings.browse_button);
+
+ // Route click event to input element programmatically, if possible
+ if (up.features.triggerDialog && browseButton) {
+ plupload.addEvent(getById(up.settings.browse_button), 'click', function(e) {
+ if (!input.disabled) {
+ input.click();
+ }
+ e.preventDefault();
+ }, up.id);
+ }
+
+ // Set input styles
+ plupload.extend(input.style, {
+ width : '100%',
+ height : '100%',
+ opacity : 0,
+ fontSize: '99px', // force input element to be bigger then needed to occupy whole space
+ cursor: 'pointer'
+ });
+
+ plupload.extend(form.style, {
+ overflow: 'hidden'
+ });
+
+ // Show the container if shim_bgcolor is specified
+ bgcolor = up.settings.shim_bgcolor;
+ if (bgcolor) {
+ form.style.background = bgcolor;
+ }
+
+ // no opacity in IE
+ if (IE) {
+ plupload.extend(input.style, {
+ filter : "alpha(opacity=0)"
+ });
+ }
+
+ // add change event
+ plupload.addEvent(input, 'change', function(e) {
+ var element = e.target, name, files = [], topElement;
+
+ if (element.value) {
+ getById('form_' + currentFileId).style.top = -0xFFFFF + "px";
+
+ // Get file name
+ name = element.value.replace(/\\/g, '/');
+ name = name.substring(name.length, name.lastIndexOf('/') + 1);
+
+ // Push files
+ files.push(new plupload.File(currentFileId, name));
+
+ // Clean-up events - they won't be needed anymore
+ if (!up.features.triggerDialog) {
+ plupload.removeAllEvents(form, up.id);
+ } else {
+ plupload.removeEvent(browseButton, 'click', up.id);
+ }
+ plupload.removeEvent(input, 'change', up.id);
+
+ // Create and position next form
+ createForm();
+
+ // Fire FilesAdded event
+ if (files.length) {
+ uploader.trigger("FilesAdded", files);
+ }
+ }
+ }, up.id);
+
+ // append to container
+ form.appendChild(input);
+ container.appendChild(form);
+
+ up.refresh();
+ }
+
+
+ function createIframe() {
+ var temp = document.createElement('div');
+
+ // Create iframe using a temp div since IE 6 won't be able to set the name using setAttribute or iframe.name
+ temp.innerHTML = '<iframe id="' + up.id + '_iframe" name="' + up.id + '_iframe" src="' + url + ':&quot;&quot;" style="display:none"></iframe>';
+ iframe = temp.firstChild;
+ container.appendChild(iframe);
+
+ // Add IFrame onload event
+ plupload.addEvent(iframe, 'load', function(e) {
+ var n = e.target, el, result;
+
+ // Ignore load event if there is no file
+ if (!currentFile) {
+ return;
+ }
+
+ try {
+ el = n.contentWindow.document || n.contentDocument || window.frames[n.id].document;
+ } catch (ex) {
+ // Probably a permission denied error
+ up.trigger('Error', {
+ code : plupload.SECURITY_ERROR,
+ message : plupload.translate('Security error.'),
+ file : currentFile
+ });
+
+ return;
+ }
+
+ // Get result
+ result = el.documentElement.innerText || el.documentElement.textContent;
+
+ // Assume no error
+ if (result) {
+ currentFile.status = plupload.DONE;
+ currentFile.loaded = 1025;
+ currentFile.percent = 100;
+
+ up.trigger('UploadProgress', currentFile);
+ up.trigger('FileUploaded', currentFile, {
+ response : result
+ });
+ }
+ }, up.id);
+ } // end createIframe
+
+ if (up.settings.container) {
+ container = getById(up.settings.container);
+ if (plupload.getStyle(container, 'position') === 'static') {
+ container.style.position = 'relative';
+ }
+ }
+
+ // Upload file
+ up.bind("UploadFile", function(up, file) {
+ var form, input;
+
+ // File upload finished
+ if (file.status == plupload.DONE || file.status == plupload.FAILED || up.state == plupload.STOPPED) {
+ return;
+ }
+
+ // Get the form and input elements
+ form = getById('form_' + file.id);
+ input = getById('input_' + file.id);
+
+ // Set input element name attribute which allows it to be submitted
+ input.setAttribute('name', up.settings.file_data_name);
+
+ // Store action
+ form.setAttribute("action", up.settings.url);
+
+ // Append multipart parameters
+ plupload.each(plupload.extend({name : file.target_name || file.name}, up.settings.multipart_params), function(value, name) {
+ var hidden = document.createElement('input');
+
+ plupload.extend(hidden, {
+ type : 'hidden',
+ name : name,
+ value : value
+ });
+
+ form.insertBefore(hidden, form.firstChild);
+ });
+
+ currentFile = file;
+
+ // Hide the current form
+ getById('form_' + currentFileId).style.top = -0xFFFFF + "px";
+
+ form.submit();
+ });
+
+
+
+ up.bind('FileUploaded', function(up) {
+ up.refresh(); // just to get the form back on top of browse_button
+ });
+
+ up.bind('StateChanged', function(up) {
+ if (up.state == plupload.STARTED) {
+ createIframe();
+ } else if (up.state == plupload.STOPPED) {
+ window.setTimeout(function() {
+ plupload.removeEvent(iframe, 'load', up.id);
+ if (iframe.parentNode) { // #382
+ iframe.parentNode.removeChild(iframe);
+ }
+ }, 0);
+ }
+
+ plupload.each(up.files, function(file, i) {
+ if (file.status === plupload.DONE || file.status === plupload.FAILED) {
+ var form = getById('form_' + file.id);
+
+ if(form){
+ form.parentNode.removeChild(form);
+ }
+ }
+ });
+ });
+
+ // Refresh button, will reposition the input form
+ up.bind("Refresh", function(up) {
+ var browseButton, topElement, hoverClass, activeClass, browsePos, browseSize, inputContainer, inputFile, zIndex;
+
+ browseButton = getById(up.settings.browse_button);
+ if (browseButton) {
+ browsePos = plupload.getPos(browseButton, getById(up.settings.container));
+ browseSize = plupload.getSize(browseButton);
+ inputContainer = getById('form_' + currentFileId);
+ inputFile = getById('input_' + currentFileId);
+
+ plupload.extend(inputContainer.style, {
+ top : browsePos.y + 'px',
+ left : browsePos.x + 'px',
+ width : browseSize.w + 'px',
+ height : browseSize.h + 'px'
+ });
+
+ // for IE and WebKit place input element underneath the browse button and route onclick event
+ // TODO: revise when browser support for this feature will change
+ if (up.features.triggerDialog) {
+ if (plupload.getStyle(browseButton, 'position') === 'static') {
+ plupload.extend(browseButton.style, {
+ position : 'relative'
+ });
+ }
+
+ zIndex = parseInt(browseButton.style.zIndex, 10);
+
+ if (isNaN(zIndex)) {
+ zIndex = 0;
+ }
+
+ plupload.extend(browseButton.style, {
+ zIndex : zIndex
+ });
+
+ plupload.extend(inputContainer.style, {
+ zIndex : zIndex - 1
+ });
+ }
+
+ /* Since we have to place input[type=file] on top of the browse_button for some browsers (FF, Opera),
+ browse_button loses interactivity, here we try to neutralize this issue highlighting browse_button
+ with a special class
+ TODO: needs to be revised as things will change */
+ hoverClass = up.settings.browse_button_hover;
+ activeClass = up.settings.browse_button_active;
+ topElement = up.features.triggerDialog ? browseButton : inputContainer;
+
+ if (hoverClass) {
+ plupload.addEvent(topElement, 'mouseover', function() {
+ plupload.addClass(browseButton, hoverClass);
+ }, up.id);
+ plupload.addEvent(topElement, 'mouseout', function() {
+ plupload.removeClass(browseButton, hoverClass);
+ }, up.id);
+ }
+
+ if (activeClass) {
+ plupload.addEvent(topElement, 'mousedown', function() {
+ plupload.addClass(browseButton, activeClass);
+ }, up.id);
+ plupload.addEvent(document.body, 'mouseup', function() {
+ plupload.removeClass(browseButton, activeClass);
+ }, up.id);
+ }
+ }
+ });
+
+ // Remove files
+ uploader.bind("FilesRemoved", function(up, files) {
+ var i, n;
+
+ for (i = 0; i < files.length; i++) {
+ n = getById('form_' + files[i].id);
+ if (n) {
+ n.parentNode.removeChild(n);
+ }
+ }
+ });
+
+ uploader.bind("DisableBrowse", function(up, disabled) {
+ var input = document.getElementById('input_' + currentFileId);
+ if (input) {
+ input.disabled = disabled;
+ }
+ });
+
+
+ // Completely destroy the runtime
+ uploader.bind("Destroy", function(up) {
+ var name, element, form,
+ elements = {
+ inputContainer: 'form_' + currentFileId,
+ inputFile: 'input_' + currentFileId,
+ browseButton: up.settings.browse_button
+ };
+
+ // Unbind event handlers
+ for (name in elements) {
+ element = getById(elements[name]);
+ if (element) {
+ plupload.removeAllEvents(element, up.id);
+ }
+ }
+ plupload.removeAllEvents(document.body, up.id);
+
+ // Remove mark-up
+ plupload.each(fileIds, function(id, i) {
+ form = getById('form_' + id);
+ if (form) {
+ form.parentNode.removeChild(form);
+ }
+ });
+
+ });
+
+ // Create initial form
+ createForm();
+ });
+
+ callback({success : true});
+ }
+ });
+})(window, document, plupload);
diff --git a/debian/missing-sources/plupload/javascript/plupload.html5.js b/debian/missing-sources/plupload/javascript/plupload.html5.js
new file mode 100644
index 0000000..4b154b8
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/plupload.html5.js
@@ -0,0 +1,1525 @@
+/**
+ * plupload.html5.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global plupload:false, File:false, window:false, atob:false, FormData:false, FileReader:false, ArrayBuffer:false, Uint8Array:false, BlobBuilder:false, unescape:false */
+
+(function(window, document, plupload, undef) {
+ var html5files = {}, // queue of original File objects
+ fakeSafariDragDrop;
+
+ /**
+ * Detect subsampling in loaded image.
+ * In iOS, larger images than 2M pixels may be subsampled in rendering.
+ */
+ function detectSubsampling(img) {
+ var iw = img.naturalWidth, ih = img.naturalHeight;
+ if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image
+ var canvas = document.createElement('canvas');
+ canvas.width = canvas.height = 1;
+ var ctx = canvas.getContext('2d');
+ ctx.drawImage(img, -iw + 1, 0);
+ // subsampled image becomes half smaller in rendering size.
+ // check alpha channel value to confirm image is covering edge pixel or not.
+ // if alpha value is 0 image is not covering, hence subsampled.
+ return ctx.getImageData(0, 0, 1, 1).data[3] === 0;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Detecting vertical squash in loaded image.
+ * Fixes a bug which squash image vertically while drawing into canvas for some images.
+ */
+ function detectVerticalSquash(img, iw, ih) {
+ var canvas = document.createElement('canvas');
+ canvas.width = 1;
+ canvas.height = ih;
+ var ctx = canvas.getContext('2d');
+ ctx.drawImage(img, 0, 0);
+ var data = ctx.getImageData(0, 0, 1, ih).data;
+ // search image edge pixel position in case it is squashed vertically.
+ var sy = 0;
+ var ey = ih;
+ var py = ih;
+ while (py > sy) {
+ var alpha = data[(py - 1) * 4 + 3];
+ if (alpha === 0) {
+ ey = py;
+ } else {
+ sy = py;
+ }
+
+ py = (ey + sy) >> 1;
+ }
+
+ var ratio = (py / ih);
+ return (ratio === 0) ? 1 : ratio;
+ }
+
+ /**
+ * Rendering image element (with resizing) into the canvas element
+ */
+ function renderImageToCanvas(img, canvas, options) {
+ var iw = img.naturalWidth, ih = img.naturalHeight;
+ var width = options.width, height = options.height;
+ var ctx = canvas.getContext('2d');
+ ctx.save();
+ var subsampled = detectSubsampling(img);
+ if (subsampled) {
+ iw /= 2;
+ ih /= 2;
+ }
+
+ var d = 1024; // size of tiling canvas
+ var tmpCanvas = document.createElement('canvas');
+ tmpCanvas.width = tmpCanvas.height = d;
+ var tmpCtx = tmpCanvas.getContext('2d');
+ var vertSquashRatio = detectVerticalSquash(img, iw, ih);
+ var sy = 0;
+ while (sy < ih) {
+ var sh = sy + d > ih ? ih - sy : d;
+ var sx = 0;
+ while (sx < iw) {
+ var sw = sx + d > iw ? iw - sx : d;
+ tmpCtx.clearRect(0, 0, d, d);
+ tmpCtx.drawImage(img, -sx, -sy);
+ var dx = (sx * width / iw) << 0;
+ var dw = Math.ceil(sw * width / iw);
+ var dy = (sy * height / ih / vertSquashRatio) << 0;
+ var dh = Math.ceil(sh * height / ih / vertSquashRatio);
+ ctx.drawImage(tmpCanvas, 0, 0, sw, sh, dx, dy, dw, dh);
+ sx += d;
+ }
+
+ sy += d;
+ }
+
+ ctx.restore();
+ tmpCanvas = tmpCtx = null;
+ }
+
+ function readFileAsDataURL(file, callback) {
+ var reader;
+
+ // Use FileReader if it's available
+ if ("FileReader" in window) {
+ reader = new FileReader();
+ reader.readAsDataURL(file);
+ reader.onload = function() {
+ callback(reader.result);
+ };
+ } else {
+ return callback(file.getAsDataURL());
+ }
+ }
+
+ function readFileAsBinary(file, callback) {
+ var reader;
+
+ // Use FileReader if it's available
+ if ("FileReader" in window) {
+ reader = new FileReader();
+ reader.readAsBinaryString(file);
+ reader.onload = function() {
+ callback(reader.result);
+ };
+ } else {
+ return callback(file.getAsBinary());
+ }
+ }
+
+ function scaleImage(file, resize, mime, callback) {
+ var canvas, context, img, scale,
+ up = this;
+
+ readFileAsDataURL(html5files[file.id], function(data) {
+ // Setup canvas and context
+ canvas = document.createElement("canvas");
+ canvas.style.display = 'none';
+ document.body.appendChild(canvas);
+
+ // Load image
+ img = new Image();
+ img.onerror = img.onabort = function() {
+ // Failed to load, the image may be invalid
+ callback({success : false});
+ };
+ img.onload = function() {
+ var width, height, percentage, jpegHeaders, exifParser;
+
+ if (!resize['width']) {
+ resize['width'] = img.width;
+ }
+
+ if (!resize['height']) {
+ resize['height'] = img.height;
+ }
+
+ scale = Math.min(resize.width / img.width, resize.height / img.height);
+
+ if (scale < 1) {
+ width = Math.round(img.width * scale);
+ height = Math.round(img.height * scale);
+ } else if (resize['quality'] && mime === 'image/jpeg') {
+ // do not upsize, but drop the quality for jpegs
+ width = img.width;
+ height = img.height;
+ } else {
+ // Image does not need to be resized
+ callback({success : false});
+ return;
+ }
+
+ // Scale image and canvas
+ canvas.width = width;
+ canvas.height = height;
+ renderImageToCanvas(img, canvas, { width: width, height: height });
+
+ // Preserve JPEG headers
+ if (mime === 'image/jpeg') {
+ jpegHeaders = new JPEG_Headers(atob(data.substring(data.indexOf('base64,') + 7)));
+ if (jpegHeaders['headers'] && jpegHeaders['headers'].length) {
+ exifParser = new ExifParser();
+
+ if (exifParser.init(jpegHeaders.get('exif')[0])) {
+ // Set new width and height
+ exifParser.setExif('PixelXDimension', width);
+ exifParser.setExif('PixelYDimension', height);
+
+ // Update EXIF header
+ jpegHeaders.set('exif', exifParser.getBinary());
+
+ // trigger Exif events only if someone listens to them
+ if (up.hasEventListener('ExifData')) {
+ up.trigger('ExifData', file, exifParser.EXIF());
+ }
+
+ if (up.hasEventListener('GpsData')) {
+ up.trigger('GpsData', file, exifParser.GPS());
+ }
+ }
+ }
+ }
+
+ if (resize['quality'] && mime === 'image/jpeg') {
+ // Try quality property first
+ try {
+ data = canvas.toDataURL(mime, resize['quality'] / 100); // used to throw an exception in Firefox
+ } catch (ex) {
+ data = canvas.toDataURL(mime);
+ }
+ } else {
+ data = canvas.toDataURL(mime);
+ }
+
+
+ // Remove data prefix information and grab the base64 encoded data and decode it
+ data = data.substring(data.indexOf('base64,') + 7);
+ data = atob(data);
+
+ // Restore JPEG headers if applicable
+ if (jpegHeaders && jpegHeaders['headers'] && jpegHeaders['headers'].length) {
+ data = jpegHeaders.restore(data);
+ jpegHeaders.purge(); // free memory
+ }
+
+ // Remove canvas and execute callback with decoded image data
+ canvas.parentNode.removeChild(canvas);
+ callback({success : true, data : data});
+ };
+
+ img.src = data;
+ });
+ }
+
+ /**
+ * HMTL5 implementation. This runtime supports these features: dragdrop, jpgresize, pngresize.
+ *
+ * @static
+ * @class plupload.runtimes.Html5
+ * @extends plupload.Runtime
+ */
+ plupload.runtimes.Html5 = plupload.addRuntime("html5", {
+ /**
+ * Returns a list of supported features for the runtime.
+ *
+ * @return {Object} Name/value object with supported features.
+ */
+ getFeatures : function() {
+ var xhr, hasXhrSupport, hasProgress, canSendBinary, dataAccessSupport, sliceSupport;
+
+ hasXhrSupport = hasProgress = dataAccessSupport = sliceSupport = false;
+
+ if (window.XMLHttpRequest) {
+ xhr = new XMLHttpRequest();
+ hasProgress = !!xhr.upload;
+ hasXhrSupport = !!(xhr.sendAsBinary || xhr.upload);
+ }
+
+ // Check for support for various features
+ if (hasXhrSupport) {
+ canSendBinary = !!(xhr.sendAsBinary || (window.Uint8Array && window.ArrayBuffer));
+
+ // Set dataAccessSupport only for Gecko since BlobBuilder and XHR doesn't handle binary data correctly
+ dataAccessSupport = !!(File && (File.prototype.getAsDataURL || window.FileReader) && canSendBinary);
+ sliceSupport = !!(File && (File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice));
+ }
+
+ // sniff out Safari for Windows and fake drag/drop
+ fakeSafariDragDrop = plupload.ua.safari && plupload.ua.windows;
+
+ return {
+ html5: hasXhrSupport, // This is a special one that we check inside the init call
+ dragdrop: (function() {
+ // this comes directly from Modernizr: http://www.modernizr.com/
+ var div = document.createElement('div');
+ return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div);
+ }()),
+ jpgresize: dataAccessSupport,
+ pngresize: dataAccessSupport,
+ multipart: dataAccessSupport || !!window.FileReader || !!window.FormData,
+ canSendBinary: canSendBinary,
+ // gecko 2/5/6 can't send blob with FormData: https://bugzilla.mozilla.org/show_bug.cgi?id=649150
+ // Android browsers (default one and Dolphin) seem to have the same issue, see: #613
+ cantSendBlobInFormData: !!(plupload.ua.gecko && window.FormData && window.FileReader && !FileReader.prototype.readAsArrayBuffer) || plupload.ua.android,
+ progress: hasProgress,
+ chunks: sliceSupport,
+ // Safari on Windows has problems when selecting multiple files
+ multi_selection: !(plupload.ua.safari && plupload.ua.windows),
+ // WebKit and Gecko 2+ can trigger file dialog progrmmatically
+ triggerDialog: (plupload.ua.gecko && window.FormData || plupload.ua.webkit)
+ };
+ },
+
+ /**
+ * Initializes the upload runtime.
+ *
+ * @method init
+ * @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
+ * @param {function} callback Callback to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
+ */
+ init : function(uploader, callback) {
+ var features, xhr;
+
+ function addSelectedFiles(native_files) {
+ var file, i, files = [], id, fileNames = {};
+
+ // Add the selected files to the file queue
+ for (i = 0; i < native_files.length; i++) {
+ file = native_files[i];
+
+ // Safari on Windows will add first file from dragged set multiple times
+ // @see: https://bugs.webkit.org/show_bug.cgi?id=37957
+ if (fileNames[file.name] && plupload.ua.safari && plupload.ua.windows) {
+ continue;
+ }
+ fileNames[file.name] = true;
+
+ // Store away gears blob internally
+ id = plupload.guid();
+ html5files[id] = file;
+
+ // Expose id, name and size
+ files.push(new plupload.File(id, file.fileName || file.name, file.fileSize || file.size)); // fileName / fileSize depricated
+ }
+
+ // Trigger FilesAdded event if we added any
+ if (files.length) {
+ uploader.trigger("FilesAdded", files);
+ }
+ }
+
+ // No HTML5 upload support
+ features = this.getFeatures();
+ if (!features.html5) {
+ callback({success : false});
+ return;
+ }
+
+ uploader.bind("Init", function(up) {
+ var inputContainer, browseButton, mimes = [], i, y, filters = up.settings.filters, ext, type, container = document.body, inputFile;
+
+ // Create input container and insert it at an absolute position within the browse button
+ inputContainer = document.createElement('div');
+ inputContainer.id = up.id + '_html5_container';
+
+ plupload.extend(inputContainer.style, {
+ position : 'absolute',
+ background : uploader.settings.shim_bgcolor || 'transparent',
+ width : '100px',
+ height : '100px',
+ overflow : 'hidden',
+ zIndex : 99999,
+ opacity : uploader.settings.shim_bgcolor ? '' : 0 // Force transparent if bgcolor is undefined
+ });
+ inputContainer.className = 'plupload html5';
+
+ if (uploader.settings.container) {
+ container = document.getElementById(uploader.settings.container);
+ if (plupload.getStyle(container, 'position') === 'static') {
+ container.style.position = 'relative';
+ }
+ }
+
+ container.appendChild(inputContainer);
+
+ // Convert extensions to mime types list
+ no_type_restriction:
+ for (i = 0; i < filters.length; i++) {
+ ext = filters[i].extensions.split(/,/);
+
+ for (y = 0; y < ext.length; y++) {
+
+ // If there's an asterisk in the list, then accept attribute is not required
+ if (ext[y] === '*') {
+ mimes = [];
+ break no_type_restriction;
+ }
+
+ type = plupload.mimeTypes[ext[y]];
+
+ if (type && plupload.inArray(type, mimes) === -1) {
+ mimes.push(type);
+ }
+ }
+ }
+
+
+ // Insert the input inside the input container
+ inputContainer.innerHTML = '<input id="' + uploader.id + '_html5" ' + ' style="font-size:999px"' +
+ ' type="file" accept="' + mimes.join(',') + '" ' +
+ (uploader.settings.multi_selection && uploader.features.multi_selection ? 'multiple="multiple"' : '') + ' />';
+
+ inputContainer.scrollTop = 100;
+ inputFile = document.getElementById(uploader.id + '_html5');
+
+ if (up.features.triggerDialog) {
+ plupload.extend(inputFile.style, {
+ position: 'absolute',
+ width: '100%',
+ height: '100%'
+ });
+ } else {
+ // shows arrow cursor instead of the text one, bit more logical
+ plupload.extend(inputFile.style, {
+ cssFloat: 'right',
+ styleFloat: 'right'
+ });
+ }
+
+ inputFile.onchange = function() {
+ // Add the selected files from file input
+ addSelectedFiles(this.files);
+
+ // Clearing the value enables the user to select the same file again if they want to
+ this.value = '';
+ };
+
+ /* Since we have to place input[type=file] on top of the browse_button for some browsers (FF, Opera),
+ browse_button loses interactivity, here we try to neutralize this issue highlighting browse_button
+ with a special classes
+ TODO: needs to be revised as things will change */
+ browseButton = document.getElementById(up.settings.browse_button);
+ if (browseButton) {
+ var hoverClass = up.settings.browse_button_hover,
+ activeClass = up.settings.browse_button_active,
+ topElement = up.features.triggerDialog ? browseButton : inputContainer;
+
+ if (hoverClass) {
+ plupload.addEvent(topElement, 'mouseover', function() {
+ plupload.addClass(browseButton, hoverClass);
+ }, up.id);
+ plupload.addEvent(topElement, 'mouseout', function() {
+ plupload.removeClass(browseButton, hoverClass);
+ }, up.id);
+ }
+
+ if (activeClass) {
+ plupload.addEvent(topElement, 'mousedown', function() {
+ plupload.addClass(browseButton, activeClass);
+ }, up.id);
+ plupload.addEvent(document.body, 'mouseup', function() {
+ plupload.removeClass(browseButton, activeClass);
+ }, up.id);
+ }
+
+ // Route click event to the input[type=file] element for supporting browsers
+ if (up.features.triggerDialog) {
+ plupload.addEvent(browseButton, 'click', function(e) {
+ var input = document.getElementById(up.id + '_html5');
+ if (input && !input.disabled) { // for some reason FF (up to 8.0.1 so far) lets to click disabled input[type=file]
+ input.click();
+ }
+ e.preventDefault();
+ }, up.id);
+ }
+ }
+ });
+
+ // Add drop handler
+ uploader.bind("PostInit", function() {
+ var dropElm = document.getElementById(uploader.settings.drop_element);
+
+ if (dropElm) {
+ // Lets fake drag/drop on Safari by moving a input type file in front of the mouse pointer when we drag into the drop zone
+ // TODO: Remove this logic once Safari has official drag/drop support
+ if (fakeSafariDragDrop) {
+ plupload.addEvent(dropElm, 'dragenter', function(e) {
+ var dropInputElm, dropPos, dropSize;
+
+ // Get or create drop zone
+ dropInputElm = document.getElementById(uploader.id + "_drop");
+ if (!dropInputElm) {
+ dropInputElm = document.createElement("input");
+ dropInputElm.setAttribute('type', "file");
+ dropInputElm.setAttribute('id', uploader.id + "_drop");
+ dropInputElm.setAttribute('multiple', 'multiple');
+
+ plupload.addEvent(dropInputElm, 'change', function() {
+ // Add the selected files from file input
+ addSelectedFiles(this.files);
+
+ // Remove input element
+ plupload.removeEvent(dropInputElm, 'change', uploader.id);
+ dropInputElm.parentNode.removeChild(dropInputElm);
+ }, uploader.id);
+
+ // avoid event propagation as Safari cancels the whole capability of dropping files if you are doing a preventDefault of this event on the document body
+ plupload.addEvent(dropInputElm, 'dragover', function(e) {
+ e.stopPropagation();
+ }, uploader.id);
+
+ dropElm.appendChild(dropInputElm);
+ }
+
+ dropPos = plupload.getPos(dropElm, document.getElementById(uploader.settings.container));
+ dropSize = plupload.getSize(dropElm);
+
+ if (plupload.getStyle(dropElm, 'position') === 'static') {
+ plupload.extend(dropElm.style, {
+ position : 'relative'
+ });
+ }
+
+ plupload.extend(dropInputElm.style, {
+ position : 'absolute',
+ display : 'block',
+ top : 0,
+ left : 0,
+ width : dropSize.w + 'px',
+ height : dropSize.h + 'px',
+ opacity : 0
+ });
+ }, uploader.id);
+
+ return;
+ }
+
+ // Block browser default drag over
+ plupload.addEvent(dropElm, 'dragover', function(e) {
+ e.preventDefault();
+ }, uploader.id);
+
+ // Attach drop handler and grab files
+ plupload.addEvent(dropElm, 'drop', function(e) {
+ var dataTransfer = e.dataTransfer;
+
+ // Add dropped files
+ if (dataTransfer && dataTransfer.files) {
+ addSelectedFiles(dataTransfer.files);
+ }
+
+ e.preventDefault();
+ }, uploader.id);
+ }
+ });
+
+ uploader.bind("Refresh", function(up) {
+ var browseButton, browsePos, browseSize, inputContainer, zIndex;
+
+ browseButton = document.getElementById(uploader.settings.browse_button);
+ if (browseButton) {
+ browsePos = plupload.getPos(browseButton, document.getElementById(up.settings.container));
+ browseSize = plupload.getSize(browseButton);
+ inputContainer = document.getElementById(uploader.id + '_html5_container');
+
+ plupload.extend(inputContainer.style, {
+ top : browsePos.y + 'px',
+ left : browsePos.x + 'px',
+ width : browseSize.w + 'px',
+ height : browseSize.h + 'px'
+ });
+
+ // for WebKit place input element underneath the browse button and route onclick event
+ // TODO: revise when browser support for this feature will change
+ if (uploader.features.triggerDialog) {
+ if (plupload.getStyle(browseButton, 'position') === 'static') {
+ plupload.extend(browseButton.style, {
+ position : 'relative'
+ });
+ }
+
+ zIndex = parseInt(plupload.getStyle(browseButton, 'zIndex'), 10);
+ if (isNaN(zIndex)) {
+ zIndex = 0;
+ }
+
+ plupload.extend(browseButton.style, {
+ zIndex : zIndex
+ });
+
+ plupload.extend(inputContainer.style, {
+ zIndex : zIndex - 1
+ });
+ }
+ }
+ });
+
+ uploader.bind("DisableBrowse", function(up, disabled) {
+ var input = document.getElementById(up.id + '_html5');
+ if (input) {
+ input.disabled = disabled;
+ }
+ });
+
+ uploader.bind("CancelUpload", function() {
+ if (xhr && xhr.abort) {
+ xhr.abort();
+ }
+ });
+
+ uploader.bind("UploadFile", function(up, file) {
+ var settings = up.settings, nativeFile, resize;
+
+ function w3cBlobSlice(blob, start, end) {
+ var blobSlice;
+
+ if (File.prototype.slice) {
+ try {
+ blob.slice(); // depricated version will throw WRONG_ARGUMENTS_ERR exception
+ return blob.slice(start, end);
+ } catch (e) {
+ // depricated slice method
+ return blob.slice(start, end - start);
+ }
+ // slice method got prefixed: https://bugzilla.mozilla.org/show_bug.cgi?id=649672
+ } else if (blobSlice = File.prototype.webkitSlice || File.prototype.mozSlice) {
+ return blobSlice.call(blob, start, end);
+ } else {
+ return null; // or throw some exception
+ }
+ }
+
+ function sendBinaryBlob(blob) {
+ var chunk = 0, loaded = 0;
+
+
+ function uploadNextChunk() {
+ var chunkBlob, br, chunks, args, chunkSize, curChunkSize, mimeType, url = up.settings.url;
+
+ function sendAsBinaryString(bin) {
+ if (xhr.sendAsBinary) { // Gecko
+ xhr.sendAsBinary(bin);
+ } else if (up.features.canSendBinary) { // WebKit with typed arrays support
+ var ui8a = new Uint8Array(bin.length);
+ for (var i = 0; i < bin.length; i++) {
+ ui8a[i] = (bin.charCodeAt(i) & 0xff);
+ }
+ xhr.send(ui8a.buffer);
+ }
+ }
+
+ function prepareAndSend(bin) {
+ var multipartDeltaSize = 0,
+ boundary = '----pluploadboundary' + plupload.guid(), formData, dashdash = '--', crlf = '\r\n', multipartBlob = '';
+
+ xhr = new XMLHttpRequest;
+
+ // Do we have upload progress support
+ if (xhr.upload) {
+ xhr.upload.onprogress = function(e) {
+ file.loaded = Math.min(file.size, loaded + e.loaded - multipartDeltaSize); // Loaded can be larger than file size due to multipart encoding
+ up.trigger('UploadProgress', file);
+ };
+ }
+
+ xhr.onreadystatechange = function() {
+ var httpStatus, chunkArgs;
+
+ if (xhr.readyState == 4 && up.state !== plupload.STOPPED) {
+ // Getting the HTTP status might fail on some Gecko versions
+ try {
+ httpStatus = xhr.status;
+ } catch (ex) {
+ httpStatus = 0;
+ }
+
+ // Is error status
+ if (httpStatus >= 400) {
+ up.trigger('Error', {
+ code : plupload.HTTP_ERROR,
+ message : plupload.translate('HTTP Error.'),
+ file : file,
+ status : httpStatus
+ });
+ } else {
+ // Handle chunk response
+ if (chunks) {
+ chunkArgs = {
+ chunk : chunk,
+ chunks : chunks,
+ response : xhr.responseText,
+ status : httpStatus
+ };
+
+ up.trigger('ChunkUploaded', file, chunkArgs);
+ loaded += curChunkSize;
+
+ // Stop upload
+ if (chunkArgs.cancelled) {
+ file.status = plupload.FAILED;
+ return;
+ }
+
+ file.loaded = Math.min(file.size, (chunk + 1) * chunkSize);
+ } else {
+ file.loaded = file.size;
+ }
+
+ up.trigger('UploadProgress', file);
+
+ bin = chunkBlob = formData = multipartBlob = null; // Free memory
+
+ // Check if file is uploaded
+ if (!chunks || ++chunk >= chunks) {
+ file.status = plupload.DONE;
+
+ up.trigger('FileUploaded', file, {
+ response : xhr.responseText,
+ status : httpStatus
+ });
+ } else {
+ // Still chunks left
+ uploadNextChunk();
+ }
+ }
+ }
+ };
+
+
+ // Build multipart request
+ if (up.settings.multipart && features.multipart) {
+
+ args.name = file.target_name || file.name;
+
+ xhr.open("post", url, true);
+
+ // Set custom headers
+ plupload.each(up.settings.headers, function(value, name) {
+ xhr.setRequestHeader(name, value);
+ });
+
+
+ // if has FormData support like Chrome 6+, Safari 5+, Firefox 4, use it
+ if (typeof(bin) !== 'string' && !!window.FormData) {
+ formData = new FormData();
+
+ // Add multipart params
+ plupload.each(plupload.extend(args, up.settings.multipart_params), function(value, name) {
+ formData.append(name, value);
+ });
+
+ // Add file and send it
+ formData.append(up.settings.file_data_name, bin);
+ xhr.send(formData);
+
+ return;
+ } // if no FormData we can still try to send it directly as last resort (see below)
+
+
+ if (typeof(bin) === 'string') {
+ // Trying to send the whole thing as binary...
+
+ // multipart request
+ xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
+
+ // append multipart parameters
+ plupload.each(plupload.extend(args, up.settings.multipart_params), function(value, name) {
+ multipartBlob += dashdash + boundary + crlf +
+ 'Content-Disposition: form-data; name="' + name + '"' + crlf + crlf;
+
+ multipartBlob += unescape(encodeURIComponent(value)) + crlf;
+ });
+
+ mimeType = plupload.mimeTypes[file.name.replace(/^.+\.([^.]+)/, '$1').toLowerCase()] || 'application/octet-stream';
+
+ // Build RFC2388 blob
+ multipartBlob += dashdash + boundary + crlf +
+ 'Content-Disposition: form-data; name="' + up.settings.file_data_name + '"; filename="' + unescape(encodeURIComponent(file.name)) + '"' + crlf +
+ 'Content-Type: ' + mimeType + crlf + crlf +
+ bin + crlf +
+ dashdash + boundary + dashdash + crlf;
+
+ multipartDeltaSize = multipartBlob.length - bin.length;
+ bin = multipartBlob;
+
+ sendAsBinaryString(bin);
+ return; // will return from here only if shouldn't send binary
+ }
+ }
+
+ // if no multipart, or last resort, send as binary stream
+ url = plupload.buildUrl(up.settings.url, plupload.extend(args, up.settings.multipart_params));
+
+ xhr.open("post", url, true);
+
+ xhr.setRequestHeader('Content-Type', 'application/octet-stream'); // Binary stream header
+
+ // Set custom headers
+ plupload.each(up.settings.headers, function(value, name) {
+ xhr.setRequestHeader(name, value);
+ });
+
+ if (typeof(bin) === 'string') {
+ sendAsBinaryString(bin);
+ } else {
+ xhr.send(bin);
+ }
+ } // prepareAndSend
+
+
+ // File upload finished
+ if (file.status == plupload.DONE || file.status == plupload.FAILED || up.state == plupload.STOPPED) {
+ return;
+ }
+
+ // Standard arguments
+ args = {name : file.target_name || file.name};
+
+ // Only add chunking args if needed
+ if (settings.chunk_size && file.size > settings.chunk_size && (features.chunks || typeof(blob) == 'string')) { // blob will be of type string if it was loaded in memory
+ chunkSize = settings.chunk_size;
+ chunks = Math.ceil(file.size / chunkSize);
+ curChunkSize = Math.min(chunkSize, file.size - (chunk * chunkSize));
+
+ // Blob is string so we need to fake chunking, this is not
+ // ideal since the whole file is loaded into memory
+ if (typeof(blob) == 'string') {
+ chunkBlob = blob.substring(chunk * chunkSize, chunk * chunkSize + curChunkSize);
+ } else {
+ // Slice the chunk
+ chunkBlob = w3cBlobSlice(blob, chunk * chunkSize, chunk * chunkSize + curChunkSize);
+ }
+
+ // Setup query string arguments
+ args.chunk = chunk;
+ args.chunks = chunks;
+ } else {
+ curChunkSize = file.size;
+ chunkBlob = blob;
+ }
+
+ // workaround for Android and Gecko 2,5,6 FormData+Blob bug: https://bugzilla.mozilla.org/show_bug.cgi?id=649150
+ if (up.settings.multipart && features.multipart && typeof(chunkBlob) !== 'string' && window.FileReader && features.cantSendBlobInFormData && features.chunks && up.settings.chunk_size) { // Gecko 2,5,6
+ (function() {
+ var fr = new FileReader(); // we need to recreate FileReader object in Android, otherwise it hangs
+ fr.onload = function() {
+ prepareAndSend(fr.result);
+ fr = null; // maybe give a hand to GC (Gecko had problems with this)
+ }
+ fr.readAsBinaryString(chunkBlob);
+ }());
+ } else {
+ prepareAndSend(chunkBlob);
+ }
+ }
+
+ // Start uploading chunks
+ uploadNextChunk();
+ }
+
+ nativeFile = html5files[file.id];
+
+ // Resize image if it's a supported format and resize is enabled
+ if (features.jpgresize && up.settings.resize && /\.(png|jpg|jpeg)$/i.test(file.name)) {
+ scaleImage.call(up, file, up.settings.resize, /\.png$/i.test(file.name) ? 'image/png' : 'image/jpeg', function(res) {
+ // If it was scaled send the scaled image if it failed then
+ // send the raw image and let the server do the scaling
+ if (res.success) {
+ file.size = res.data.length;
+ sendBinaryBlob(res.data);
+ } else if (features.chunks) {
+ sendBinaryBlob(nativeFile);
+ } else {
+ readFileAsBinary(nativeFile, sendBinaryBlob); // for browsers not supporting File.slice (e.g. FF3.6)
+ }
+ });
+ // if there's no way to slice file without preloading it in memory, preload it
+ } else if (!features.chunks && features.jpgresize) {
+ readFileAsBinary(nativeFile, sendBinaryBlob);
+ } else {
+ sendBinaryBlob(nativeFile);
+ }
+ });
+
+
+ uploader.bind('Destroy', function(up) {
+ var name, element, container = document.body,
+ elements = {
+ inputContainer: up.id + '_html5_container',
+ inputFile: up.id + '_html5',
+ browseButton: up.settings.browse_button,
+ dropElm: up.settings.drop_element
+ };
+
+ // Unbind event handlers
+ for (name in elements) {
+ element = document.getElementById(elements[name]);
+ if (element) {
+ plupload.removeAllEvents(element, up.id);
+ }
+ }
+ plupload.removeAllEvents(document.body, up.id);
+
+ if (up.settings.container) {
+ container = document.getElementById(up.settings.container);
+ }
+
+ // Remove mark-up
+ container.removeChild(document.getElementById(elements.inputContainer));
+ });
+
+ callback({success : true});
+ }
+ });
+
+ function BinaryReader() {
+ var II = false, bin;
+
+ // Private functions
+ function read(idx, size) {
+ var mv = II ? 0 : -8 * (size - 1), sum = 0, i;
+
+ for (i = 0; i < size; i++) {
+ sum |= (bin.charCodeAt(idx + i) << Math.abs(mv + i*8));
+ }
+
+ return sum;
+ }
+
+ function putstr(segment, idx, length) {
+ var length = arguments.length === 3 ? length : bin.length - idx - 1;
+
+ bin = bin.substr(0, idx) + segment + bin.substr(length + idx);
+ }
+
+ function write(idx, num, size) {
+ var str = '', mv = II ? 0 : -8 * (size - 1), i;
+
+ for (i = 0; i < size; i++) {
+ str += String.fromCharCode((num >> Math.abs(mv + i*8)) & 255);
+ }
+
+ putstr(str, idx, size);
+ }
+
+ // Public functions
+ return {
+ II: function(order) {
+ if (order === undef) {
+ return II;
+ } else {
+ II = order;
+ }
+ },
+
+ init: function(binData) {
+ II = false;
+ bin = binData;
+ },
+
+ SEGMENT: function(idx, length, segment) {
+ switch (arguments.length) {
+ case 1:
+ return bin.substr(idx, bin.length - idx - 1);
+ case 2:
+ return bin.substr(idx, length);
+ case 3:
+ putstr(segment, idx, length);
+ break;
+ default: return bin;
+ }
+ },
+
+ BYTE: function(idx) {
+ return read(idx, 1);
+ },
+
+ SHORT: function(idx) {
+ return read(idx, 2);
+ },
+
+ LONG: function(idx, num) {
+ if (num === undef) {
+ return read(idx, 4);
+ } else {
+ write(idx, num, 4);
+ }
+ },
+
+ SLONG: function(idx) { // 2's complement notation
+ var num = read(idx, 4);
+
+ return (num > 2147483647 ? num - 4294967296 : num);
+ },
+
+ STRING: function(idx, size) {
+ var str = '';
+
+ for (size += idx; idx < size; idx++) {
+ str += String.fromCharCode(read(idx, 1));
+ }
+
+ return str;
+ }
+ };
+ }
+
+ function JPEG_Headers(data) {
+
+ var markers = {
+ 0xFFE1: {
+ app: 'EXIF',
+ name: 'APP1',
+ signature: "Exif\0"
+ },
+ 0xFFE2: {
+ app: 'ICC',
+ name: 'APP2',
+ signature: "ICC_PROFILE\0"
+ },
+ 0xFFED: {
+ app: 'IPTC',
+ name: 'APP13',
+ signature: "Photoshop 3.0\0"
+ }
+ },
+ headers = [], read, idx, marker = undef, length = 0, limit;
+
+
+ read = new BinaryReader();
+ read.init(data);
+
+ // Check if data is jpeg
+ if (read.SHORT(0) !== 0xFFD8) {
+ return;
+ }
+
+ idx = 2;
+ limit = Math.min(1048576, data.length);
+
+ while (idx <= limit) {
+ marker = read.SHORT(idx);
+
+ // omit RST (restart) markers
+ if (marker >= 0xFFD0 && marker <= 0xFFD7) {
+ idx += 2;
+ continue;
+ }
+
+ // no headers allowed after SOS marker
+ if (marker === 0xFFDA || marker === 0xFFD9) {
+ break;
+ }
+
+ length = read.SHORT(idx + 2) + 2;
+
+ if (markers[marker] &&
+ read.STRING(idx + 4, markers[marker].signature.length) === markers[marker].signature) {
+ headers.push({
+ hex: marker,
+ app: markers[marker].app.toUpperCase(),
+ name: markers[marker].name.toUpperCase(),
+ start: idx,
+ length: length,
+ segment: read.SEGMENT(idx, length)
+ });
+ }
+ idx += length;
+ }
+
+ read.init(null); // free memory
+
+ return {
+
+ headers: headers,
+
+ restore: function(data) {
+ read.init(data);
+
+ // Check if data is jpeg
+ var jpegHeaders = new JPEG_Headers(data);
+
+ if (!jpegHeaders['headers']) {
+ return false;
+ }
+
+ // Delete any existing headers that need to be replaced
+ for (var i = jpegHeaders['headers'].length; i > 0; i--) {
+ var hdr = jpegHeaders['headers'][i - 1];
+ read.SEGMENT(hdr.start, hdr.length, '')
+ }
+ jpegHeaders.purge();
+
+ idx = read.SHORT(2) == 0xFFE0 ? 4 + read.SHORT(4) : 2;
+
+ for (var i = 0, max = headers.length; i < max; i++) {
+ read.SEGMENT(idx, 0, headers[i].segment);
+ idx += headers[i].length;
+ }
+
+ return read.SEGMENT();
+ },
+
+ get: function(app) {
+ var array = [];
+
+ for (var i = 0, max = headers.length; i < max; i++) {
+ if (headers[i].app === app.toUpperCase()) {
+ array.push(headers[i].segment);
+ }
+ }
+ return array;
+ },
+
+ set: function(app, segment) {
+ var array = [];
+
+ if (typeof(segment) === 'string') {
+ array.push(segment);
+ } else {
+ array = segment;
+ }
+
+ for (var i = ii = 0, max = headers.length; i < max; i++) {
+ if (headers[i].app === app.toUpperCase()) {
+ headers[i].segment = array[ii];
+ headers[i].length = array[ii].length;
+ ii++;
+ }
+ if (ii >= array.length) break;
+ }
+ },
+
+ purge: function() {
+ headers = [];
+ read.init(null);
+ }
+ };
+ }
+
+
+ function ExifParser() {
+ // Private ExifParser fields
+ var data, tags, offsets = {}, tagDescs;
+
+ data = new BinaryReader();
+
+ tags = {
+ tiff : {
+ /*
+ The image orientation viewed in terms of rows and columns.
+
+ 1 - The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side.
+ 2 - The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side.
+ 3 - The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side.
+ 4 - The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side.
+ 5 - The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side.
+ 6 - The 0th row is the visual left-hand side of the image, and the 0th column is the visual top.
+ 7 - The 0th row is the visual right-hand side of the image, and the 0th column is the visual top.
+ 8 - The 0th row is the visual right-hand side of the image, and the 0th column is the visual bottom.
+ 9 - The 0th row is the visual left-hand side of the image, and the 0th column is the visual bottom.
+ */
+ 0x0112: 'Orientation',
+ 0x8769: 'ExifIFDPointer',
+ 0x8825: 'GPSInfoIFDPointer'
+ },
+ exif : {
+ 0x9000: 'ExifVersion',
+ 0xA001: 'ColorSpace',
+ 0xA002: 'PixelXDimension',
+ 0xA003: 'PixelYDimension',
+ 0x9003: 'DateTimeOriginal',
+ 0x829A: 'ExposureTime',
+ 0x829D: 'FNumber',
+ 0x8827: 'ISOSpeedRatings',
+ 0x9201: 'ShutterSpeedValue',
+ 0x9202: 'ApertureValue' ,
+ 0x9207: 'MeteringMode',
+ 0x9208: 'LightSource',
+ 0x9209: 'Flash',
+ 0xA402: 'ExposureMode',
+ 0xA403: 'WhiteBalance',
+ 0xA406: 'SceneCaptureType',
+ 0xA404: 'DigitalZoomRatio',
+ 0xA408: 'Contrast',
+ 0xA409: 'Saturation',
+ 0xA40A: 'Sharpness'
+ },
+ gps : {
+ 0x0000: 'GPSVersionID',
+ 0x0001: 'GPSLatitudeRef',
+ 0x0002: 'GPSLatitude',
+ 0x0003: 'GPSLongitudeRef',
+ 0x0004: 'GPSLongitude'
+ }
+ };
+
+ tagDescs = {
+ 'ColorSpace': {
+ 1: 'sRGB',
+ 0: 'Uncalibrated'
+ },
+
+ 'MeteringMode': {
+ 0: 'Unknown',
+ 1: 'Average',
+ 2: 'CenterWeightedAverage',
+ 3: 'Spot',
+ 4: 'MultiSpot',
+ 5: 'Pattern',
+ 6: 'Partial',
+ 255: 'Other'
+ },
+
+ 'LightSource': {
+ 1: 'Daylight',
+ 2: 'Fliorescent',
+ 3: 'Tungsten',
+ 4: 'Flash',
+ 9: 'Fine weather',
+ 10: 'Cloudy weather',
+ 11: 'Shade',
+ 12: 'Daylight fluorescent (D 5700 - 7100K)',
+ 13: 'Day white fluorescent (N 4600 -5400K)',
+ 14: 'Cool white fluorescent (W 3900 - 4500K)',
+ 15: 'White fluorescent (WW 3200 - 3700K)',
+ 17: 'Standard light A',
+ 18: 'Standard light B',
+ 19: 'Standard light C',
+ 20: 'D55',
+ 21: 'D65',
+ 22: 'D75',
+ 23: 'D50',
+ 24: 'ISO studio tungsten',
+ 255: 'Other'
+ },
+
+ 'Flash': {
+ 0x0000: 'Flash did not fire.',
+ 0x0001: 'Flash fired.',
+ 0x0005: 'Strobe return light not detected.',
+ 0x0007: 'Strobe return light detected.',
+ 0x0009: 'Flash fired, compulsory flash mode',
+ 0x000D: 'Flash fired, compulsory flash mode, return light not detected',
+ 0x000F: 'Flash fired, compulsory flash mode, return light detected',
+ 0x0010: 'Flash did not fire, compulsory flash mode',
+ 0x0018: 'Flash did not fire, auto mode',
+ 0x0019: 'Flash fired, auto mode',
+ 0x001D: 'Flash fired, auto mode, return light not detected',
+ 0x001F: 'Flash fired, auto mode, return light detected',
+ 0x0020: 'No flash function',
+ 0x0041: 'Flash fired, red-eye reduction mode',
+ 0x0045: 'Flash fired, red-eye reduction mode, return light not detected',
+ 0x0047: 'Flash fired, red-eye reduction mode, return light detected',
+ 0x0049: 'Flash fired, compulsory flash mode, red-eye reduction mode',
+ 0x004D: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected',
+ 0x004F: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected',
+ 0x0059: 'Flash fired, auto mode, red-eye reduction mode',
+ 0x005D: 'Flash fired, auto mode, return light not detected, red-eye reduction mode',
+ 0x005F: 'Flash fired, auto mode, return light detected, red-eye reduction mode'
+ },
+
+ 'ExposureMode': {
+ 0: 'Auto exposure',
+ 1: 'Manual exposure',
+ 2: 'Auto bracket'
+ },
+
+ 'WhiteBalance': {
+ 0: 'Auto white balance',
+ 1: 'Manual white balance'
+ },
+
+ 'SceneCaptureType': {
+ 0: 'Standard',
+ 1: 'Landscape',
+ 2: 'Portrait',
+ 3: 'Night scene'
+ },
+
+ 'Contrast': {
+ 0: 'Normal',
+ 1: 'Soft',
+ 2: 'Hard'
+ },
+
+ 'Saturation': {
+ 0: 'Normal',
+ 1: 'Low saturation',
+ 2: 'High saturation'
+ },
+
+ 'Sharpness': {
+ 0: 'Normal',
+ 1: 'Soft',
+ 2: 'Hard'
+ },
+
+ // GPS related
+ 'GPSLatitudeRef': {
+ N: 'North latitude',
+ S: 'South latitude'
+ },
+
+ 'GPSLongitudeRef': {
+ E: 'East longitude',
+ W: 'West longitude'
+ }
+ };
+
+ function extractTags(IFD_offset, tags2extract) {
+ var length = data.SHORT(IFD_offset), i, ii,
+ tag, type, count, tagOffset, offset, value, values = [], hash = {};
+
+ for (i = 0; i < length; i++) {
+ // Set binary reader pointer to beginning of the next tag
+ offset = tagOffset = IFD_offset + 12 * i + 2;
+
+ tag = tags2extract[data.SHORT(offset)];
+
+ if (tag === undef) {
+ continue; // Not the tag we requested
+ }
+
+ type = data.SHORT(offset+=2);
+ count = data.LONG(offset+=2);
+
+ offset += 4;
+ values = [];
+
+ switch (type) {
+ case 1: // BYTE
+ case 7: // UNDEFINED
+ if (count > 4) {
+ offset = data.LONG(offset) + offsets.tiffHeader;
+ }
+
+ for (ii = 0; ii < count; ii++) {
+ values[ii] = data.BYTE(offset + ii);
+ }
+
+ break;
+
+ case 2: // STRING
+ if (count > 4) {
+ offset = data.LONG(offset) + offsets.tiffHeader;
+ }
+
+ hash[tag] = data.STRING(offset, count - 1);
+
+ continue;
+
+ case 3: // SHORT
+ if (count > 2) {
+ offset = data.LONG(offset) + offsets.tiffHeader;
+ }
+
+ for (ii = 0; ii < count; ii++) {
+ values[ii] = data.SHORT(offset + ii*2);
+ }
+
+ break;
+
+ case 4: // LONG
+ if (count > 1) {
+ offset = data.LONG(offset) + offsets.tiffHeader;
+ }
+
+ for (ii = 0; ii < count; ii++) {
+ values[ii] = data.LONG(offset + ii*4);
+ }
+
+ break;
+
+ case 5: // RATIONAL
+ offset = data.LONG(offset) + offsets.tiffHeader;
+
+ for (ii = 0; ii < count; ii++) {
+ values[ii] = data.LONG(offset + ii*4) / data.LONG(offset + ii*4 + 4);
+ }
+
+ break;
+
+ case 9: // SLONG
+ offset = data.LONG(offset) + offsets.tiffHeader;
+
+ for (ii = 0; ii < count; ii++) {
+ values[ii] = data.SLONG(offset + ii*4);
+ }
+
+ break;
+
+ case 10: // SRATIONAL
+ offset = data.LONG(offset) + offsets.tiffHeader;
+
+ for (ii = 0; ii < count; ii++) {
+ values[ii] = data.SLONG(offset + ii*4) / data.SLONG(offset + ii*4 + 4);
+ }
+
+ break;
+
+ default:
+ continue;
+ }
+
+ value = (count == 1 ? values[0] : values);
+
+ if (tagDescs.hasOwnProperty(tag) && typeof value != 'object') {
+ hash[tag] = tagDescs[tag][value];
+ } else {
+ hash[tag] = value;
+ }
+ }
+
+ return hash;
+ }
+
+ function getIFDOffsets() {
+ var Tiff = undef, idx = offsets.tiffHeader;
+
+ // Set read order of multi-byte data
+ data.II(data.SHORT(idx) == 0x4949);
+
+ // Check if always present bytes are indeed present
+ if (data.SHORT(idx+=2) !== 0x002A) {
+ return false;
+ }
+
+ offsets['IFD0'] = offsets.tiffHeader + data.LONG(idx += 2);
+ Tiff = extractTags(offsets['IFD0'], tags.tiff);
+
+ offsets['exifIFD'] = ('ExifIFDPointer' in Tiff ? offsets.tiffHeader + Tiff.ExifIFDPointer : undef);
+ offsets['gpsIFD'] = ('GPSInfoIFDPointer' in Tiff ? offsets.tiffHeader + Tiff.GPSInfoIFDPointer : undef);
+
+ return true;
+ }
+
+ // At the moment only setting of simple (LONG) values, that do not require offset recalculation, is supported
+ function setTag(ifd, tag, value) {
+ var offset, length, tagOffset, valueOffset = 0;
+
+ // If tag name passed translate into hex key
+ if (typeof(tag) === 'string') {
+ var tmpTags = tags[ifd.toLowerCase()];
+ for (hex in tmpTags) {
+ if (tmpTags[hex] === tag) {
+ tag = hex;
+ break;
+ }
+ }
+ }
+ offset = offsets[ifd.toLowerCase() + 'IFD'];
+ length = data.SHORT(offset);
+
+ for (i = 0; i < length; i++) {
+ tagOffset = offset + 12 * i + 2;
+
+ if (data.SHORT(tagOffset) == tag) {
+ valueOffset = tagOffset + 8;
+ break;
+ }
+ }
+
+ if (!valueOffset) return false;
+
+
+ data.LONG(valueOffset, value);
+ return true;
+ }
+
+
+ // Public functions
+ return {
+ init: function(segment) {
+ // Reset internal data
+ offsets = {
+ tiffHeader: 10
+ };
+
+ if (segment === undef || !segment.length) {
+ return false;
+ }
+
+ data.init(segment);
+
+ // Check if that's APP1 and that it has EXIF
+ if (data.SHORT(0) === 0xFFE1 && data.STRING(4, 5).toUpperCase() === "EXIF\0") {
+ return getIFDOffsets();
+ }
+ return false;
+ },
+
+ EXIF: function() {
+ var Exif;
+
+ // Populate EXIF hash
+ Exif = extractTags(offsets.exifIFD, tags.exif);
+
+ // Fix formatting of some tags
+ if (Exif.ExifVersion && plupload.typeOf(Exif.ExifVersion) === 'array') {
+ for (var i = 0, exifVersion = ''; i < Exif.ExifVersion.length; i++) {
+ exifVersion += String.fromCharCode(Exif.ExifVersion[i]);
+ }
+ Exif.ExifVersion = exifVersion;
+ }
+
+ return Exif;
+ },
+
+ GPS: function() {
+ var GPS;
+
+ GPS = extractTags(offsets.gpsIFD, tags.gps);
+
+ // iOS devices (and probably some others) do not put in GPSVersionID tag (why?..)
+ if (GPS.GPSVersionID) {
+ GPS.GPSVersionID = GPS.GPSVersionID.join('.');
+ }
+
+ return GPS;
+ },
+
+ setExif: function(tag, value) {
+ // Right now only setting of width/height is possible
+ if (tag !== 'PixelXDimension' && tag !== 'PixelYDimension') return false;
+
+ return setTag('exif', tag, value);
+ },
+
+
+ getBinary: function() {
+ return data.SEGMENT();
+ }
+ };
+ };
+})(window, document, plupload);
diff --git a/debian/missing-sources/plupload/javascript/plupload.js b/debian/missing-sources/plupload/javascript/plupload.js
new file mode 100644
index 0000000..94156df
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/plupload.js
@@ -0,0 +1,1774 @@
+/**
+ * plupload.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global window:false, escape:false */
+
+/*!@@version@@*/
+
+(function() {
+ var count = 0, runtimes = [], i18n = {}, mimes = {},
+ xmlEncodeChars = {'<' : 'lt', '>' : 'gt', '&' : 'amp', '"' : 'quot', '\'' : '#39'},
+ xmlEncodeRegExp = /[<>&\"\']/g, undef, delay = window.setTimeout,
+ // A place to store references to event handlers
+ eventhash = {},
+ uid;
+
+ // IE W3C like event funcs
+ function preventDefault() {
+ this.returnValue = false;
+ }
+
+ function stopPropagation() {
+ this.cancelBubble = true;
+ }
+
+ // Parses the default mime types string into a mimes lookup map
+ (function(mime_data) {
+ var items = mime_data.split(/,/), i, y, ext;
+
+ for (i = 0; i < items.length; i += 2) {
+ ext = items[i + 1].split(/ /);
+
+ for (y = 0; y < ext.length; y++) {
+ mimes[ext[y]] = items[i];
+ }
+ }
+ })(
+ "application/msword,doc dot," +
+ "application/pdf,pdf," +
+ "application/pgp-signature,pgp," +
+ "application/postscript,ps ai eps," +
+ "application/rtf,rtf," +
+ "application/vnd.ms-excel,xls xlb," +
+ "application/vnd.ms-powerpoint,ppt pps pot," +
+ "application/zip,zip," +
+ "application/x-shockwave-flash,swf swfl," +
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx," +
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx," +
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx," +
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx," +
+ "application/vnd.openxmlformats-officedocument.presentationml.template,potx," +
+ "application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx," +
+ "application/x-javascript,js," +
+ "application/json,json," +
+ "audio/mpeg,mpga mpega mp2 mp3," +
+ "audio/x-wav,wav," +
+ "audio/mp4,m4a," +
+ "image/bmp,bmp," +
+ "image/gif,gif," +
+ "image/jpeg,jpeg jpg jpe," +
+ "image/photoshop,psd," +
+ "image/png,png," +
+ "image/svg+xml,svg svgz," +
+ "image/tiff,tiff tif," +
+ "text/plain,asc txt text diff log," +
+ "text/html,htm html xhtml," +
+ "text/css,css," +
+ "text/csv,csv," +
+ "text/rtf,rtf," +
+ "video/mpeg,mpeg mpg mpe m2v," +
+ "video/quicktime,qt mov," +
+ "video/mp4,mp4," +
+ "video/x-m4v,m4v," +
+ "video/x-flv,flv," +
+ "video/x-ms-wmv,wmv," +
+ "video/avi,avi," +
+ "video/webm,webm," +
+ "video/3gpp,3gp," +
+ "video/3gpp2,3g2," +
+ "video/vnd.rn-realvideo,rv," +
+ "application/vnd.oasis.opendocument.formula-template,otf," +
+ "application/octet-stream,exe"
+ );
+
+ /**
+ * Plupload class with some global constants and functions.
+ *
+ * @example
+ * // Encode entities
+ * console.log(plupload.xmlEncode("My string &lt;&gt;"));
+ *
+ * // Generate unique id
+ * console.log(plupload.guid());
+ *
+ * @static
+ * @class plupload
+ */
+ var plupload = {
+ /**
+ * Plupload version will be replaced on build.
+ */
+ VERSION : '@@version@@',
+
+ /**
+ * Inital state of the queue and also the state ones it's finished all it's uploads.
+ *
+ * @property STOPPED
+ * @final
+ */
+ STOPPED : 1,
+
+ /**
+ * Upload process is running
+ *
+ * @property STARTED
+ * @final
+ */
+ STARTED : 2,
+
+ /**
+ * File is queued for upload
+ *
+ * @property QUEUED
+ * @final
+ */
+ QUEUED : 1,
+
+ /**
+ * File is being uploaded
+ *
+ * @property UPLOADING
+ * @final
+ */
+ UPLOADING : 2,
+
+ /**
+ * File has failed to be uploaded
+ *
+ * @property FAILED
+ * @final
+ */
+ FAILED : 4,
+
+ /**
+ * File has been uploaded successfully
+ *
+ * @property DONE
+ * @final
+ */
+ DONE : 5,
+
+ // Error constants used by the Error event
+
+ /**
+ * Generic error for example if an exception is thrown inside Silverlight.
+ *
+ * @property GENERIC_ERROR
+ * @final
+ */
+ GENERIC_ERROR : -100,
+
+ /**
+ * HTTP transport error. For example if the server produces a HTTP status other than 200.
+ *
+ * @property HTTP_ERROR
+ * @final
+ */
+ HTTP_ERROR : -200,
+
+ /**
+ * Generic I/O error. For exampe if it wasn't possible to open the file stream on local machine.
+ *
+ * @property IO_ERROR
+ * @final
+ */
+ IO_ERROR : -300,
+
+ /**
+ * Generic I/O error. For exampe if it wasn't possible to open the file stream on local machine.
+ *
+ * @property SECURITY_ERROR
+ * @final
+ */
+ SECURITY_ERROR : -400,
+
+ /**
+ * Initialization error. Will be triggered if no runtime was initialized.
+ *
+ * @property INIT_ERROR
+ * @final
+ */
+ INIT_ERROR : -500,
+
+ /**
+ * File size error. If the user selects a file that is too large it will be blocked and an error of this type will be triggered.
+ *
+ * @property FILE_SIZE_ERROR
+ * @final
+ */
+ FILE_SIZE_ERROR : -600,
+
+ /**
+ * File extension error. If the user selects a file that isn't valid according to the filters setting.
+ *
+ * @property FILE_EXTENSION_ERROR
+ * @final
+ */
+ FILE_EXTENSION_ERROR : -601,
+
+ /**
+ * Runtime will try to detect if image is proper one. Otherwise will throw this error.
+ *
+ * @property IMAGE_FORMAT_ERROR
+ * @final
+ */
+ IMAGE_FORMAT_ERROR : -700,
+
+ /**
+ * While working on the image runtime will try to detect if the operation may potentially run out of memeory and will throw this error.
+ *
+ * @property IMAGE_MEMORY_ERROR
+ * @final
+ */
+ IMAGE_MEMORY_ERROR : -701,
+
+ /**
+ * Each runtime has an upper limit on a dimension of the image it can handle. If bigger, will throw this error.
+ *
+ * @property IMAGE_DIMENSIONS_ERROR
+ * @final
+ */
+ IMAGE_DIMENSIONS_ERROR : -702,
+
+
+ /**
+ * Mime type lookup table.
+ *
+ * @property mimeTypes
+ * @type Object
+ * @final
+ */
+ mimeTypes : mimes,
+
+ /**
+ * In some cases sniffing is the only way around :(
+ */
+ ua: (function() {
+ var nav = navigator, userAgent = nav.userAgent, vendor = nav.vendor, webkit, opera, safari;
+
+ webkit = /WebKit/.test(userAgent);
+ safari = webkit && vendor.indexOf('Apple') !== -1;
+ opera = window.opera && window.opera.buildNumber;
+
+ return {
+ windows: navigator.platform.indexOf('Win') !== -1,
+ android: /Android/.test(userAgent),
+ ie: !webkit && !opera && (/MSIE/gi).test(userAgent) && (/Explorer/gi).test(nav.appName),
+ webkit: webkit,
+ gecko: !webkit && /Gecko/.test(userAgent),
+ safari: safari,
+ opera: !!opera
+ };
+ }()),
+
+ /**
+ * Gets the true type of the built-in object (better version of typeof).
+ * @credits Angus Croll (http://javascriptweblog.wordpress.com/)
+ *
+ * @param {Object} o Object to check.
+ * @return {String} Object [[Class]]
+ */
+ typeOf: function(o) {
+ return ({}).toString.call(o).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
+ },
+
+ /**
+ * Extends the specified object with another object.
+ *
+ * @method extend
+ * @param {Object} target Object to extend.
+ * @param {Object..} obj Multiple objects to extend with.
+ * @return {Object} Same as target, the extended object.
+ */
+ extend : function(target) {
+ plupload.each(arguments, function(arg, i) {
+ if (i > 0) {
+ plupload.each(arg, function(value, key) {
+ target[key] = value;
+ });
+ }
+ });
+
+ return target;
+ },
+
+ /**
+ * Cleans the specified name from national characters (diacritics). The result will be a name with only a-z, 0-9 and _.
+ *
+ * @method cleanName
+ * @param {String} s String to clean up.
+ * @return {String} Cleaned string.
+ */
+ cleanName : function(name) {
+ var i, lookup;
+
+ // Replace diacritics
+ lookup = [
+ /[\300-\306]/g, 'A', /[\340-\346]/g, 'a',
+ /\307/g, 'C', /\347/g, 'c',
+ /[\310-\313]/g, 'E', /[\350-\353]/g, 'e',
+ /[\314-\317]/g, 'I', /[\354-\357]/g, 'i',
+ /\321/g, 'N', /\361/g, 'n',
+ /[\322-\330]/g, 'O', /[\362-\370]/g, 'o',
+ /[\331-\334]/g, 'U', /[\371-\374]/g, 'u'
+ ];
+
+ for (i = 0; i < lookup.length; i += 2) {
+ name = name.replace(lookup[i], lookup[i + 1]);
+ }
+
+ // Replace whitespace
+ name = name.replace(/\s+/g, '_');
+
+ // Remove anything else
+ name = name.replace(/[^a-z0-9_\-\.]+/gi, '');
+
+ return name;
+ },
+
+ /**
+ * Adds a specific upload runtime like for example flash or gears.
+ *
+ * @method addRuntime
+ * @param {String} name Runtime name for example flash.
+ * @param {Object} obj Object containing init/destroy method.
+ */
+ addRuntime : function(name, runtime) {
+ runtime.name = name;
+ runtimes[name] = runtime;
+ runtimes.push(runtime);
+
+ return runtime;
+ },
+
+ /**
+ * Generates an unique ID. This is 99.99% unique since it takes the current time and 5 random numbers.
+ * The only way a user would be able to get the same ID is if the two persons at the same exact milisecond manages
+ * to get 5 the same random numbers between 0-65535 it also uses a counter so each call will be guaranteed to be page unique.
+ * It's more probable for the earth to be hit with an ansteriod. You can also if you want to be 100% sure set the plupload.guidPrefix property
+ * to an user unique key.
+ *
+ * @method guid
+ * @return {String} Virtually unique id.
+ */
+ guid : function() {
+ var guid = new Date().getTime().toString(32), i;
+
+ for (i = 0; i < 5; i++) {
+ guid += Math.floor(Math.random() * 65535).toString(32);
+ }
+
+ return (plupload.guidPrefix || 'p') + guid + (count++).toString(32);
+ },
+
+ /**
+ * Builds a full url out of a base URL and an object with items to append as query string items.
+ *
+ * @param {String} url Base URL to append query string items to.
+ * @param {Object} items Name/value object to serialize as a querystring.
+ * @return {String} String with url + serialized query string items.
+ */
+ buildUrl : function(url, items) {
+ var query = '';
+
+ plupload.each(items, function(value, name) {
+ query += (query ? '&' : '') + encodeURIComponent(name) + '=' + encodeURIComponent(value);
+ });
+
+ if (query) {
+ url += (url.indexOf('?') > 0 ? '&' : '?') + query;
+ }
+
+ return url;
+ },
+
+ /**
+ * Executes the callback function for each item in array/object. If you return false in the
+ * callback it will break the loop.
+ *
+ * @param {Object} obj Object to iterate.
+ * @param {function} callback Callback function to execute for each item.
+ */
+ each : function(obj, callback) {
+ var length, key, i;
+
+ if (obj) {
+ length = obj.length;
+
+ if (length === undef) {
+ // Loop object items
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ if (callback(obj[key], key) === false) {
+ return;
+ }
+ }
+ }
+ } else {
+ // Loop array items
+ for (i = 0; i < length; i++) {
+ if (callback(obj[i], i) === false) {
+ return;
+ }
+ }
+ }
+ }
+ },
+
+ /**
+ * Formats the specified number as a size string for example 1024 becomes 1 KB.
+ *
+ * @method formatSize
+ * @param {Number} size Size to format as string.
+ * @return {String} Formatted size string.
+ */
+ formatSize : function(size) {
+ if (size === undef || /\D/.test(size)) {
+ return plupload.translate('N/A');
+ }
+
+ // GB
+ if (size > 1073741824) {
+ return Math.round(size / 1073741824, 1) + " GB";
+ }
+
+ // MB
+ if (size > 1048576) {
+ return Math.round(size / 1048576, 1) + " MB";
+ }
+
+ // KB
+ if (size > 1024) {
+ return Math.round(size / 1024, 1) + " KB";
+ }
+
+ return size + " b";
+ },
+
+ /**
+ * Returns the absolute x, y position of an Element. The position will be returned in a object with x, y fields.
+ *
+ * @method getPos
+ * @param {Element} node HTML element or element id to get x, y position from.
+ * @param {Element} root Optional root element to stop calculations at.
+ * @return {object} Absolute position of the specified element object with x, y fields.
+ */
+ getPos : function(node, root) {
+ var x = 0, y = 0, parent, doc = document, nodeRect, rootRect;
+
+ node = node;
+ root = root || doc.body;
+
+ // Returns the x, y cordinate for an element on IE 6 and IE 7
+ function getIEPos(node) {
+ var bodyElm, rect, x = 0, y = 0;
+
+ if (node) {
+ rect = node.getBoundingClientRect();
+ bodyElm = doc.compatMode === "CSS1Compat" ? doc.documentElement : doc.body;
+ x = rect.left + bodyElm.scrollLeft;
+ y = rect.top + bodyElm.scrollTop;
+ }
+
+ return {
+ x : x,
+ y : y
+ };
+ }
+
+ // Use getBoundingClientRect on IE 6 and IE 7 but not on IE 8 in standards mode
+ if (node && node.getBoundingClientRect && plupload.ua.ie && (!doc.documentMode || doc.documentMode < 8)) {
+ nodeRect = getIEPos(node);
+ rootRect = getIEPos(root);
+
+ return {
+ x : nodeRect.x - rootRect.x,
+ y : nodeRect.y - rootRect.y
+ };
+ }
+
+ parent = node;
+ while (parent && parent != root && parent.nodeType) {
+ x += parent.offsetLeft || 0;
+ y += parent.offsetTop || 0;
+ parent = parent.offsetParent;
+ }
+
+ parent = node.parentNode;
+ while (parent && parent != root && parent.nodeType) {
+ x -= parent.scrollLeft || 0;
+ y -= parent.scrollTop || 0;
+ parent = parent.parentNode;
+ }
+
+ return {
+ x : x,
+ y : y
+ };
+ },
+
+ /**
+ * Returns the size of the specified node in pixels.
+ *
+ * @param {Node} node Node to get the size of.
+ * @return {Object} Object with a w and h property.
+ */
+ getSize : function(node) {
+ return {
+ w : node.offsetWidth || node.clientWidth,
+ h : node.offsetHeight || node.clientHeight
+ };
+ },
+
+ /**
+ * Parses the specified size string into a byte value. For example 10kb becomes 10240.
+ *
+ * @method parseSize
+ * @param {String/Number} size String to parse or number to just pass through.
+ * @return {Number} Size in bytes.
+ */
+ parseSize : function(size) {
+ var mul;
+
+ if (typeof(size) == 'string') {
+ size = /^([0-9]+)([mgk]?)$/.exec(size.toLowerCase().replace(/[^0-9mkg]/g, ''));
+ mul = size[2];
+ size = +size[1];
+
+ if (mul == 'g') {
+ size *= 1073741824;
+ }
+
+ if (mul == 'm') {
+ size *= 1048576;
+ }
+
+ if (mul == 'k') {
+ size *= 1024;
+ }
+ }
+
+ return size;
+ },
+
+ /**
+ * Encodes the specified string.
+ *
+ * @method xmlEncode
+ * @param {String} s String to encode.
+ * @return {String} Encoded string.
+ */
+ xmlEncode : function(str) {
+ return str ? ('' + str).replace(xmlEncodeRegExp, function(chr) {
+ return xmlEncodeChars[chr] ? '&' + xmlEncodeChars[chr] + ';' : chr;
+ }) : str;
+ },
+
+ /**
+ * Forces anything into an array.
+ *
+ * @method toArray
+ * @param {Object} obj Object with length field.
+ * @return {Array} Array object containing all items.
+ */
+ toArray : function(obj) {
+ var i, arr = [];
+
+ for (i = 0; i < obj.length; i++) {
+ arr[i] = obj[i];
+ }
+
+ return arr;
+ },
+
+ /**
+ * Find an element in array and return it's index if present, otherwise return -1.
+ *
+ * @method inArray
+ * @param {mixed} needle Element to find
+ * @param {Array} array
+ * @return {Int} Index of the element, or -1 if not found
+ */
+ inArray : function(needle, array) {
+ if (array) {
+ if (Array.prototype.indexOf) {
+ return Array.prototype.indexOf.call(array, needle);
+ }
+
+ for (var i = 0, length = array.length; i < length; i++) {
+ if (array[i] === needle) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ },
+
+ /**
+ * Extends the language pack object with new items.
+ *
+ * @param {Object} pack Language pack items to add.
+ * @return {Object} Extended language pack object.
+ */
+ addI18n : function(pack) {
+ return plupload.extend(i18n, pack);
+ },
+
+ /**
+ * Translates the specified string by checking for the english string in the language pack lookup.
+ *
+ * @param {String} str String to look for.
+ * @return {String} Translated string or the input string if it wasn't found.
+ */
+ translate : function(str) {
+ return i18n[str] || str;
+ },
+
+ /**
+ * Checks if object is empty.
+ *
+ * @param {Object} obj Object to check.
+ * @return {Boolean}
+ */
+ isEmptyObj : function(obj) {
+ if (obj === undef) return true;
+
+ for (var prop in obj) {
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * Checks if specified DOM element has specified class.
+ *
+ * @param {Object} obj DOM element like object to add handler to.
+ * @param {String} name Class name
+ */
+ hasClass : function(obj, name) {
+ var regExp;
+
+ if (obj.className == '') {
+ return false;
+ }
+
+ regExp = new RegExp("(^|\\s+)"+name+"(\\s+|$)");
+
+ return regExp.test(obj.className);
+ },
+
+ /**
+ * Adds specified className to specified DOM element.
+ *
+ * @param {Object} obj DOM element like object to add handler to.
+ * @param {String} name Class name
+ */
+ addClass : function(obj, name) {
+ if (!plupload.hasClass(obj, name)) {
+ obj.className = obj.className == '' ? name : obj.className.replace(/\s+$/, '')+' '+name;
+ }
+ },
+
+ /**
+ * Removes specified className from specified DOM element.
+ *
+ * @param {Object} obj DOM element like object to add handler to.
+ * @param {String} name Class name
+ */
+ removeClass : function(obj, name) {
+ var regExp = new RegExp("(^|\\s+)"+name+"(\\s+|$)");
+
+ obj.className = obj.className.replace(regExp, function($0, $1, $2) {
+ return $1 === ' ' && $2 === ' ' ? ' ' : '';
+ });
+ },
+
+ /**
+ * Returns a given computed style of a DOM element.
+ *
+ * @param {Object} obj DOM element like object.
+ * @param {String} name Style you want to get from the DOM element
+ */
+ getStyle : function(obj, name) {
+ if (obj.currentStyle) {
+ return obj.currentStyle[name];
+ } else if (window.getComputedStyle) {
+ return window.getComputedStyle(obj, null)[name];
+ }
+ },
+
+ /**
+ * Adds an event handler to the specified object and store reference to the handler
+ * in objects internal Plupload registry (@see removeEvent).
+ *
+ * @param {Object} obj DOM element like object to add handler to.
+ * @param {String} name Name to add event listener to.
+ * @param {Function} callback Function to call when event occurs.
+ * @param {String} (optional) key that might be used to add specifity to the event record.
+ */
+ addEvent : function(obj, name, callback) {
+ var func, events, types, key;
+
+ // if passed in, event will be locked with this key - one would need to provide it to removeEvent
+ key = arguments[3];
+
+ name = name.toLowerCase();
+
+ // Initialize unique identifier if needed
+ if (uid === undef) {
+ uid = 'Plupload_' + plupload.guid();
+ }
+
+ // Add event listener
+ if (obj.addEventListener) {
+ func = callback;
+
+ obj.addEventListener(name, func, false);
+ } else if (obj.attachEvent) {
+
+ func = function() {
+ var evt = window.event;
+
+ if (!evt.target) {
+ evt.target = evt.srcElement;
+ }
+
+ evt.preventDefault = preventDefault;
+ evt.stopPropagation = stopPropagation;
+
+ callback(evt);
+ };
+ obj.attachEvent('on' + name, func);
+ }
+
+ // Log event handler to objects internal Plupload registry
+ if (obj[uid] === undef) {
+ obj[uid] = plupload.guid();
+ }
+
+ if (!eventhash.hasOwnProperty(obj[uid])) {
+ eventhash[obj[uid]] = {};
+ }
+
+ events = eventhash[obj[uid]];
+
+ if (!events.hasOwnProperty(name)) {
+ events[name] = [];
+ }
+
+ events[name].push({
+ func: func,
+ orig: callback, // store original callback for IE
+ key: key
+ });
+ },
+
+
+ /**
+ * Remove event handler from the specified object. If third argument (callback)
+ * is not specified remove all events with the specified name.
+ *
+ * @param {Object} obj DOM element to remove event listener(s) from.
+ * @param {String} name Name of event listener to remove.
+ * @param {Function|String} (optional) might be a callback or unique key to match.
+ */
+ removeEvent: function(obj, name) {
+ var type, callback, key;
+
+ // match the handler either by callback or by key
+ if (typeof(arguments[2]) == "function") {
+ callback = arguments[2];
+ } else {
+ key = arguments[2];
+ }
+
+ name = name.toLowerCase();
+
+ if (obj[uid] && eventhash[obj[uid]] && eventhash[obj[uid]][name]) {
+ type = eventhash[obj[uid]][name];
+ } else {
+ return;
+ }
+
+
+ for (var i=type.length-1; i>=0; i--) {
+ // undefined or not, key should match
+ if (type[i].key === key || type[i].orig === callback) {
+
+ if (obj.removeEventListener) {
+ obj.removeEventListener(name, type[i].func, false);
+ } else if (obj.detachEvent) {
+ obj.detachEvent('on'+name, type[i].func);
+ }
+
+ type[i].orig = null;
+ type[i].func = null;
+
+ type.splice(i, 1);
+
+ // If callback was passed we are done here, otherwise proceed
+ if (callback !== undef) {
+ break;
+ }
+ }
+ }
+
+ // If event array got empty, remove it
+ if (!type.length) {
+ delete eventhash[obj[uid]][name];
+ }
+
+ // If Plupload registry has become empty, remove it
+ if (plupload.isEmptyObj(eventhash[obj[uid]])) {
+ delete eventhash[obj[uid]];
+
+ // IE doesn't let you remove DOM object property with - delete
+ try {
+ delete obj[uid];
+ } catch(e) {
+ obj[uid] = undef;
+ }
+ }
+ },
+
+
+ /**
+ * Remove all kind of events from the specified object
+ *
+ * @param {Object} obj DOM element to remove event listeners from.
+ * @param {String} (optional) unique key to match, when removing events.
+ */
+ removeAllEvents: function(obj) {
+ var key = arguments[1];
+
+ if (obj[uid] === undef || !obj[uid]) {
+ return;
+ }
+
+ plupload.each(eventhash[obj[uid]], function(events, name) {
+ plupload.removeEvent(obj, name, key);
+ });
+ }
+ };
+
+
+ /**
+ * Uploader class, an instance of this class will be created for each upload field.
+ *
+ * @example
+ * var uploader = new plupload.Uploader({
+ * runtimes : 'gears,html5,flash',
+ * browse_button : 'button_id'
+ * });
+ *
+ * uploader.bind('Init', function(up) {
+ * alert('Supports drag/drop: ' + (!!up.features.dragdrop));
+ * });
+ *
+ * uploader.bind('FilesAdded', function(up, files) {
+ * alert('Selected files: ' + files.length);
+ * });
+ *
+ * uploader.bind('QueueChanged', function(up) {
+ * alert('Queued files: ' + uploader.files.length);
+ * });
+ *
+ * uploader.init();
+ *
+ * @class plupload.Uploader
+ */
+
+ /**
+ * Constructs a new uploader instance.
+ *
+ * @constructor
+ * @method Uploader
+ * @param {Object} settings Initialization settings, to be used by the uploader instance and runtimes.
+ */
+ plupload.Uploader = function(settings) {
+ var events = {}, total, files = [], startTime, disabled = false;
+
+ // Inital total state
+ total = new plupload.QueueProgress();
+
+ // Default settings
+ settings = plupload.extend({
+ chunk_size : 0,
+ multipart : true,
+ multi_selection : true,
+ file_data_name : 'file',
+ filters : []
+ }, settings);
+
+ // Private methods
+ function uploadNext() {
+ var file, count = 0, i;
+
+ if (this.state == plupload.STARTED) {
+ // Find first QUEUED file
+ for (i = 0; i < files.length; i++) {
+ if (!file && files[i].status == plupload.QUEUED) {
+ file = files[i];
+ file.status = plupload.UPLOADING;
+ if (this.trigger("BeforeUpload", file)) {
+ this.trigger("UploadFile", file);
+ }
+ } else {
+ count++;
+ }
+ }
+
+ // All files are DONE or FAILED
+ if (count == files.length) {
+ this.stop();
+ this.trigger("UploadComplete", files);
+ }
+ }
+ }
+
+ function calc() {
+ var i, file;
+
+ // Reset stats
+ total.reset();
+
+ // Check status, size, loaded etc on all files
+ for (i = 0; i < files.length; i++) {
+ file = files[i];
+
+ if (file.size !== undef) {
+ total.size += file.size;
+ total.loaded += file.loaded;
+ } else {
+ total.size = undef;
+ }
+
+ if (file.status == plupload.DONE) {
+ total.uploaded++;
+ } else if (file.status == plupload.FAILED) {
+ total.failed++;
+ } else {
+ total.queued++;
+ }
+ }
+
+ // If we couldn't calculate a total file size then use the number of files to calc percent
+ if (total.size === undef) {
+ total.percent = files.length > 0 ? Math.ceil(total.uploaded / files.length * 100) : 0;
+ } else {
+ total.bytesPerSec = Math.ceil(total.loaded / ((+new Date() - startTime || 1) / 1000.0));
+ total.percent = total.size > 0 ? Math.ceil(total.loaded / total.size * 100) : 0;
+ }
+ }
+
+ // Add public methods
+ plupload.extend(this, {
+ /**
+ * Current state of the total uploading progress. This one can either be plupload.STARTED or plupload.STOPPED.
+ * These states are controlled by the stop/start methods. The default value is STOPPED.
+ *
+ * @property state
+ * @type Number
+ */
+ state : plupload.STOPPED,
+
+ /**
+ * Current runtime name.
+ *
+ * @property runtime
+ * @type String
+ */
+ runtime: '',
+
+ /**
+ * Map of features that are available for the uploader runtime. Features will be filled
+ * before the init event is called, these features can then be used to alter the UI for the end user.
+ * Some of the current features that might be in this map is: dragdrop, chunks, jpgresize, pngresize.
+ *
+ * @property features
+ * @type Object
+ */
+ features : {},
+
+ /**
+ * Current upload queue, an array of File instances.
+ *
+ * @property files
+ * @type Array
+ * @see plupload.File
+ */
+ files : files,
+
+ /**
+ * Object with name/value settings.
+ *
+ * @property settings
+ * @type Object
+ */
+ settings : settings,
+
+ /**
+ * Total progess information. How many files has been uploaded, total percent etc.
+ *
+ * @property total
+ * @type plupload.QueueProgress
+ */
+ total : total,
+
+ /**
+ * Unique id for the Uploader instance.
+ *
+ * @property id
+ * @type String
+ */
+ id : plupload.guid(),
+
+ /**
+ * Initializes the Uploader instance and adds internal event listeners.
+ *
+ * @method init
+ */
+ init : function() {
+ var self = this, i, runtimeList, a, runTimeIndex = 0, items;
+
+ if (typeof(settings.preinit) == "function") {
+ settings.preinit(self);
+ } else {
+ plupload.each(settings.preinit, function(func, name) {
+ self.bind(name, func);
+ });
+ }
+
+ settings.page_url = settings.page_url || document.location.pathname.replace(/\/[^\/]+$/g, '/');
+
+ // If url is relative force it absolute to the current page
+ if (!/^(\w+:\/\/|\/)/.test(settings.url)) {
+ settings.url = settings.page_url + settings.url;
+ }
+
+ // Convert settings
+ settings.chunk_size = plupload.parseSize(settings.chunk_size);
+ settings.max_file_size = plupload.parseSize(settings.max_file_size);
+
+ // Add files to queue
+ self.bind('FilesAdded', function(up, selected_files) {
+ var i, file, count = 0, extensionsRegExp, filters = settings.filters;
+
+ // Convert extensions to regexp
+ if (filters && filters.length) {
+ extensionsRegExp = [];
+
+ plupload.each(filters, function(filter) {
+ plupload.each(filter.extensions.split(/,/), function(ext) {
+ if (/^\s*\*\s*$/.test(ext)) {
+ extensionsRegExp.push('\\.*');
+ } else {
+ extensionsRegExp.push('\\.' + ext.replace(new RegExp('[' + ('/^$.*+?|()[]{}\\'.replace(/./g, '\\$&')) + ']', 'g'), '\\$&'));
+ }
+ });
+ });
+
+ extensionsRegExp = new RegExp(extensionsRegExp.join('|') + '$', 'i');
+ }
+
+ for (i = 0; i < selected_files.length; i++) {
+ file = selected_files[i];
+ file.loaded = 0;
+ file.percent = 0;
+ file.status = plupload.QUEUED;
+
+ // Invalid file extension
+ if (extensionsRegExp && !extensionsRegExp.test(file.name)) {
+ up.trigger('Error', {
+ code : plupload.FILE_EXTENSION_ERROR,
+ message : plupload.translate('File extension error.'),
+ file : file
+ });
+
+ continue;
+ }
+
+ // Invalid file size
+ if (file.size !== undef && file.size > settings.max_file_size) {
+ up.trigger('Error', {
+ code : plupload.FILE_SIZE_ERROR,
+ message : plupload.translate('File size error.'),
+ file : file
+ });
+
+ continue;
+ }
+
+ // Add valid file to list
+ files.push(file);
+ count++;
+ }
+
+ // Only trigger QueueChanged event if any files where added
+ if (count) {
+ delay(function() {
+ self.trigger("QueueChanged");
+ self.refresh();
+ }, 1);
+ } else {
+ return false; // Stop the FilesAdded event from immediate propagation
+ }
+ });
+
+ // Generate unique target filenames
+ if (settings.unique_names) {
+ self.bind("UploadFile", function(up, file) {
+ var matches = file.name.match(/\.([^.]+)$/), ext = "tmp";
+
+ if (matches) {
+ ext = matches[1];
+ }
+
+ file.target_name = file.id + '.' + ext;
+ });
+ }
+
+ self.bind('UploadProgress', function(up, file) {
+ file.percent = file.size > 0 ? Math.ceil(file.loaded / file.size * 100) : 100;
+ calc();
+ });
+
+ self.bind('StateChanged', function(up) {
+ if (up.state == plupload.STARTED) {
+ // Get start time to calculate bps
+ startTime = (+new Date());
+
+ } else if (up.state == plupload.STOPPED) {
+ // Reset currently uploading files
+ for (i = up.files.length - 1; i >= 0; i--) {
+ if (up.files[i].status == plupload.UPLOADING) {
+ up.files[i].status = plupload.QUEUED;
+ calc();
+ }
+ }
+ }
+ });
+
+ self.bind('QueueChanged', calc);
+
+ self.bind("Error", function(up, err) {
+ // Set failed status if an error occured on a file
+ if (err.file) {
+ err.file.status = plupload.FAILED;
+ calc();
+
+ // Upload next file but detach it from the error event
+ // since other custom listeners might want to stop the queue
+ if (up.state == plupload.STARTED) {
+ delay(function() {
+ uploadNext.call(self);
+ }, 1);
+ }
+ }
+ });
+
+ self.bind("FileUploaded", function(up, file) {
+ file.status = plupload.DONE;
+ file.loaded = file.size;
+ up.trigger('UploadProgress', file);
+
+ // Upload next file but detach it from the error event
+ // since other custom listeners might want to stop the queue
+ delay(function() {
+ uploadNext.call(self);
+ }, 1);
+ });
+
+ // Setup runtimeList
+ if (settings.runtimes) {
+ runtimeList = [];
+ items = settings.runtimes.split(/\s?,\s?/);
+
+ for (i = 0; i < items.length; i++) {
+ if (runtimes[items[i]]) {
+ runtimeList.push(runtimes[items[i]]);
+ }
+ }
+ } else {
+ runtimeList = runtimes;
+ }
+
+ // Call init on each runtime in sequence
+ function callNextInit() {
+ var runtime = runtimeList[runTimeIndex++], features, requiredFeatures, i;
+
+ if (runtime) {
+ features = runtime.getFeatures();
+
+ // Check if runtime supports required features
+ requiredFeatures = self.settings.required_features;
+ if (requiredFeatures) {
+ requiredFeatures = requiredFeatures.split(',');
+
+ for (i = 0; i < requiredFeatures.length; i++) {
+ // Specified feature doesn't exist
+ if (!features[requiredFeatures[i]]) {
+ callNextInit();
+ return;
+ }
+ }
+ }
+
+ // Try initializing the runtime
+ runtime.init(self, function(res) {
+ if (res && res.success) {
+ // Successful initialization
+ self.features = features;
+ self.runtime = runtime.name;
+ self.trigger('Init', {runtime : runtime.name});
+ self.trigger('PostInit');
+ self.refresh();
+ } else {
+ callNextInit();
+ }
+ });
+ } else {
+ // Trigger an init error if we run out of runtimes
+ self.trigger('Error', {
+ code : plupload.INIT_ERROR,
+ message : plupload.translate('Init error.')
+ });
+ }
+ }
+
+ callNextInit();
+
+ if (typeof(settings.init) == "function") {
+ settings.init(self);
+ } else {
+ plupload.each(settings.init, function(func, name) {
+ self.bind(name, func);
+ });
+ }
+ },
+
+ /**
+ * Refreshes the upload instance by dispatching out a refresh event to all runtimes.
+ * This would for example reposition flash/silverlight shims on the page.
+ *
+ * @method refresh
+ */
+ refresh : function() {
+ this.trigger("Refresh");
+ },
+
+ /**
+ * Starts uploading the queued files.
+ *
+ * @method start
+ */
+ start : function() {
+ if (files.length && this.state != plupload.STARTED) {
+ this.state = plupload.STARTED;
+ this.trigger("StateChanged");
+
+ uploadNext.call(this);
+ }
+ },
+
+ /**
+ * Stops the upload of the queued files.
+ *
+ * @method stop
+ */
+ stop : function() {
+ if (this.state != plupload.STOPPED) {
+ this.state = plupload.STOPPED;
+ this.trigger("CancelUpload");
+ this.trigger("StateChanged");
+ }
+ },
+
+ /**
+ * Disables/enables browse button on request.
+ *
+ * @method disableBrowse
+ * @param {Boolean} disable Whether to disable or enable (default: true)
+ */
+ disableBrowse : function() {
+ disabled = arguments[0] !== undef ? arguments[0] : true;
+ this.trigger("DisableBrowse", disabled);
+ },
+
+ /**
+ * Returns the specified file object by id.
+ *
+ * @method getFile
+ * @param {String} id File id to look for.
+ * @return {plupload.File} File object or undefined if it wasn't found;
+ */
+ getFile : function(id) {
+ var i;
+
+ for (i = files.length - 1; i >= 0; i--) {
+ if (files[i].id === id) {
+ return files[i];
+ }
+ }
+ },
+
+ /**
+ * Removes a specific file.
+ *
+ * @method removeFile
+ * @param {plupload.File} file File to remove from queue.
+ */
+ removeFile : function(file) {
+ var i;
+
+ for (i = files.length - 1; i >= 0; i--) {
+ if (files[i].id === file.id) {
+ return this.splice(i, 1)[0];
+ }
+ }
+ },
+
+ /**
+ * Removes part of the queue and returns the files removed. This will also trigger the FilesRemoved and QueueChanged events.
+ *
+ * @method splice
+ * @param {Number} start (Optional) Start index to remove from.
+ * @param {Number} length (Optional) Lengh of items to remove.
+ * @return {Array} Array of files that was removed.
+ */
+ splice : function(start, length) {
+ var removed;
+
+ // Splice and trigger events
+ removed = files.splice(start === undef ? 0 : start, length === undef ? files.length : length);
+
+ this.trigger("FilesRemoved", removed);
+ this.trigger("QueueChanged");
+
+ return removed;
+ },
+
+ /**
+ * Dispatches the specified event name and it's arguments to all listeners.
+ *
+ *
+ * @method trigger
+ * @param {String} name Event name to fire.
+ * @param {Object..} Multiple arguments to pass along to the listener functions.
+ */
+ trigger : function(name) {
+ var list = events[name.toLowerCase()], i, args;
+
+ // console.log(name, arguments);
+
+ if (list) {
+ // Replace name with sender in args
+ args = Array.prototype.slice.call(arguments);
+ args[0] = this;
+
+ // Dispatch event to all listeners
+ for (i = 0; i < list.length; i++) {
+ // Fire event, break chain if false is returned
+ if (list[i].func.apply(list[i].scope, args) === false) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ },
+
+ /**
+ * Check whether uploader has any listeners to the specified event.
+ *
+ * @method hasEventListener
+ * @param {String} name Event name to check for.
+ */
+ hasEventListener : function(name) {
+ return !!events[name.toLowerCase()];
+ },
+
+ /**
+ * Adds an event listener by name.
+ *
+ * @method bind
+ * @param {String} name Event name to listen for.
+ * @param {function} func Function to call ones the event gets fired.
+ * @param {Object} scope Optional scope to execute the specified function in.
+ */
+ bind : function(name, func, scope) {
+ var list;
+
+ name = name.toLowerCase();
+ list = events[name] || [];
+ list.push({func : func, scope : scope || this});
+ events[name] = list;
+ },
+
+ /**
+ * Removes the specified event listener.
+ *
+ * @method unbind
+ * @param {String} name Name of event to remove.
+ * @param {function} func Function to remove from listener.
+ */
+ unbind : function(name) {
+ name = name.toLowerCase();
+
+ var list = events[name], i, func = arguments[1];
+
+ if (list) {
+ if (func !== undef) {
+ for (i = list.length - 1; i >= 0; i--) {
+ if (list[i].func === func) {
+ list.splice(i, 1);
+ break;
+ }
+ }
+ } else {
+ list = [];
+ }
+
+ // delete event list if it has become empty
+ if (!list.length) {
+ delete events[name];
+ }
+ }
+ },
+
+ /**
+ * Removes all event listeners.
+ *
+ * @method unbindAll
+ */
+ unbindAll : function() {
+ var self = this;
+
+ plupload.each(events, function(list, name) {
+ self.unbind(name);
+ });
+ },
+
+ /**
+ * Destroys Plupload instance and cleans after itself.
+ *
+ * @method destroy
+ */
+ destroy : function() {
+ this.stop();
+ this.trigger('Destroy');
+
+ // Clean-up after uploader itself
+ this.unbindAll();
+ }
+
+ /**
+ * Fires when the current RunTime has been initialized.
+ *
+ * @event Init
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ */
+
+ /**
+ * Fires after the init event incase you need to perform actions there.
+ *
+ * @event PostInit
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ */
+
+ /**
+ * Fires when the silverlight/flash or other shim needs to move.
+ *
+ * @event Refresh
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ */
+
+ /**
+ * Fires when the overall state is being changed for the upload queue.
+ *
+ * @event StateChanged
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ */
+
+ /**
+ * Fires when a file is to be uploaded by the runtime.
+ *
+ * @event UploadFile
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ * @param {plupload.File} file File to be uploaded.
+ */
+
+ /**
+ * Fires when just before a file is uploaded. This event enables you to override settings
+ * on the uploader instance before the file is uploaded.
+ *
+ * @event BeforeUpload
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ * @param {plupload.File} file File to be uploaded.
+ */
+
+ /**
+ * Fires when the file queue is changed. In other words when files are added/removed to the files array of the uploader instance.
+ *
+ * @event QueueChanged
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ */
+
+ /**
+ * Fires while a file is being uploaded. Use this event to update the current file upload progress.
+ *
+ * @event UploadProgress
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ * @param {plupload.File} file File that is currently being uploaded.
+ */
+
+ /**
+ * Fires while a file was removed from queue.
+ *
+ * @event FilesRemoved
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ * @param {Array} files Array of files that got removed.
+ */
+
+ /**
+ * Fires while when the user selects files to upload.
+ *
+ * @event FilesAdded
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ * @param {Array} files Array of file objects that was added to queue/selected by the user.
+ */
+
+ /**
+ * Fires when a file is successfully uploaded.
+ *
+ * @event FileUploaded
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ * @param {plupload.File} file File that was uploaded.
+ * @param {Object} response Object with response properties.
+ */
+
+ /**
+ * Fires when file chunk is uploaded.
+ *
+ * @event ChunkUploaded
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ * @param {plupload.File} file File that the chunk was uploaded for.
+ * @param {Object} response Object with response properties.
+ */
+
+ /**
+ * Fires when all files in a queue are uploaded.
+ *
+ * @event UploadComplete
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ * @param {Array} files Array of file objects that was added to queue/selected by the user.
+ */
+
+ /**
+ * Fires when a error occurs.
+ *
+ * @event Error
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ * @param {Object} error Contains code, message and sometimes file and other details.
+ */
+
+ /**
+ * Fires when destroy method is called.
+ *
+ * @event Destroy
+ * @param {plupload.Uploader} uploader Uploader instance sending the event.
+ */
+ });
+ };
+
+ /**
+ * File instance.
+ *
+ * @class plupload.File
+ * @param {String} name Name of the file.
+ * @param {Number} size File size.
+ */
+
+ /**
+ * Constructs a new file instance.
+ *
+ * @constructor
+ * @method File
+ * @param {String} id Unique file id.
+ * @param {String} name File name.
+ * @param {Number} size File size in bytes.
+ */
+ plupload.File = function(id, name, size) {
+ var self = this; // Setup alias for self to reduce code size when it's compressed
+
+ /**
+ * File id this is a globally unique id for the specific file.
+ *
+ * @property id
+ * @type String
+ */
+ self.id = id;
+
+ /**
+ * File name for example "myfile.gif".
+ *
+ * @property name
+ * @type String
+ */
+ self.name = name;
+
+ /**
+ * File size in bytes.
+ *
+ * @property size
+ * @type Number
+ */
+ self.size = size;
+
+ /**
+ * Number of bytes uploaded of the files total size.
+ *
+ * @property loaded
+ * @type Number
+ */
+ self.loaded = 0;
+
+ /**
+ * Number of percentage uploaded of the file.
+ *
+ * @property percent
+ * @type Number
+ */
+ self.percent = 0;
+
+ /**
+ * Status constant matching the plupload states QUEUED, UPLOADING, FAILED, DONE.
+ *
+ * @property status
+ * @type Number
+ * @see plupload
+ */
+ self.status = 0;
+ };
+
+ /**
+ * Runtime class gets implemented by each upload runtime.
+ *
+ * @class plupload.Runtime
+ * @static
+ */
+ plupload.Runtime = function() {
+ /**
+ * Returns a list of supported features for the runtime.
+ *
+ * @return {Object} Name/value object with supported features.
+ */
+ this.getFeatures = function() {
+ };
+
+ /**
+ * Initializes the upload runtime. This method should add necessary items to the DOM and register events needed for operation.
+ *
+ * @method init
+ * @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
+ * @param {function} callback Callback function to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
+ */
+ this.init = function(uploader, callback) {
+ };
+ };
+
+ /**
+ * Runtime class gets implemented by each upload runtime.
+ *
+ * @class plupload.QueueProgress
+ */
+
+ /**
+ * Constructs a queue progress.
+ *
+ * @constructor
+ * @method QueueProgress
+ */
+ plupload.QueueProgress = function() {
+ var self = this; // Setup alias for self to reduce code size when it's compressed
+
+ /**
+ * Total queue file size.
+ *
+ * @property size
+ * @type Number
+ */
+ self.size = 0;
+
+ /**
+ * Total bytes uploaded.
+ *
+ * @property loaded
+ * @type Number
+ */
+ self.loaded = 0;
+
+ /**
+ * Number of files uploaded.
+ *
+ * @property uploaded
+ * @type Number
+ */
+ self.uploaded = 0;
+
+ /**
+ * Number of files failed to upload.
+ *
+ * @property failed
+ * @type Number
+ */
+ self.failed = 0;
+
+ /**
+ * Number of files yet to be uploaded.
+ *
+ * @property queued
+ * @type Number
+ */
+ self.queued = 0;
+
+ /**
+ * Total percent of the uploaded bytes.
+ *
+ * @property percent
+ * @type Number
+ */
+ self.percent = 0;
+
+ /**
+ * Bytes uploaded per second.
+ *
+ * @property bytesPerSec
+ * @type Number
+ */
+ self.bytesPerSec = 0;
+
+ /**
+ * Resets the progress to it's initial values.
+ *
+ * @method reset
+ */
+ self.reset = function() {
+ self.size = self.loaded = self.uploaded = self.failed = self.queued = self.percent = self.bytesPerSec = 0;
+ };
+ };
+
+ // Create runtimes namespace
+ plupload.runtimes = {};
+
+ // Expose plupload namespace
+ window.plupload = plupload;
+})();
diff --git a/debian/missing-sources/plupload/javascript/plupload.silverlight.js b/debian/missing-sources/plupload/javascript/plupload.silverlight.js
new file mode 100644
index 0000000..c0903f2
--- /dev/null
+++ b/debian/missing-sources/plupload/javascript/plupload.silverlight.js
@@ -0,0 +1,447 @@
+/**
+ * plupload.silverlight.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global window:false, document:false, plupload:false, ActiveXObject:false */
+
+(function(window, document, plupload, undef) {
+ var uploadInstances = {}, initialized = {};
+
+ function jsonSerialize(obj) {
+ var value, type = typeof obj, isArray, i, key;
+
+ // Treat undefined as null
+ if (obj === undef || obj === null) {
+ return 'null';
+ }
+
+ // Encode strings
+ if (type === 'string') {
+ value = '\bb\tt\nn\ff\rr\""\'\'\\\\';
+
+ return '"' + obj.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g, function(a, b) {
+ var idx = value.indexOf(b);
+
+ if (idx + 1) {
+ return '\\' + value.charAt(idx + 1);
+ }
+
+ a = b.charCodeAt().toString(16);
+
+ return '\\u' + '0000'.substring(a.length) + a;
+ }) + '"';
+ }
+
+ // Loop objects/arrays
+ if (type == 'object') {
+ isArray = obj.length !== undef;
+ value = '';
+
+ if (isArray) {
+ for (i = 0; i < obj.length; i++) {
+ if (value) {
+ value += ',';
+ }
+
+ value += jsonSerialize(obj[i]);
+ }
+
+ value = '[' + value + ']';
+ } else {
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ if (value) {
+ value += ',';
+ }
+
+ value += jsonSerialize(key) + ':' + jsonSerialize(obj[key]);
+ }
+ }
+
+ value = '{' + value + '}';
+ }
+
+ return value;
+ }
+
+ // Convert all other types to string
+ return '' + obj;
+ }
+
+ function isInstalled(version) {
+ var isVersionSupported = false, container = null, control = null, actualVer,
+ actualVerArray, reqVerArray, requiredVersionPart, actualVersionPart, index = 0;
+
+ try {
+ try {
+ control = new ActiveXObject('AgControl.AgControl');
+
+ if (control.IsVersionSupported(version)) {
+ isVersionSupported = true;
+ }
+
+ control = null;
+ } catch (e) {
+ var plugin = navigator.plugins["Silverlight Plug-In"];
+
+ if (plugin) {
+ actualVer = plugin.description;
+
+ if (actualVer === "1.0.30226.2") {
+ actualVer = "2.0.30226.2";
+ }
+
+ actualVerArray = actualVer.split(".");
+
+ while (actualVerArray.length > 3) {
+ actualVerArray.pop();
+ }
+
+ while ( actualVerArray.length < 4) {
+ actualVerArray.push(0);
+ }
+
+ reqVerArray = version.split(".");
+
+ while (reqVerArray.length > 4) {
+ reqVerArray.pop();
+ }
+
+ do {
+ requiredVersionPart = parseInt(reqVerArray[index], 10);
+ actualVersionPart = parseInt(actualVerArray[index], 10);
+ index++;
+ } while (index < reqVerArray.length && requiredVersionPart === actualVersionPart);
+
+ if (requiredVersionPart <= actualVersionPart && !isNaN(requiredVersionPart)) {
+ isVersionSupported = true;
+ }
+ }
+ }
+ } catch (e2) {
+ isVersionSupported = false;
+ }
+
+ return isVersionSupported;
+ }
+
+ plupload.silverlight = {
+ trigger : function(id, name) {
+ var uploader = uploadInstances[id], i, args;
+
+ if (uploader) {
+ args = plupload.toArray(arguments).slice(1);
+ args[0] = 'Silverlight:' + name;
+
+ // Detach the call so that error handling in the browser is presented correctly
+ setTimeout(function() {
+ uploader.trigger.apply(uploader, args);
+ }, 0);
+ }
+ }
+ };
+
+ /**
+ * Silverlight implementation. This runtime supports these features: jpgresize, pngresize, chunks.
+ *
+ * @static
+ * @class plupload.runtimes.Silverlight
+ * @extends plupload.Runtime
+ */
+ plupload.runtimes.Silverlight = plupload.addRuntime("silverlight", {
+ /**
+ * Returns a list of supported features for the runtime.
+ *
+ * @return {Object} Name/value object with supported features.
+ */
+ getFeatures : function() {
+ return {
+ jpgresize: true,
+ pngresize: true,
+ chunks: true,
+ progress: true,
+ multipart: true,
+ multi_selection: true
+ };
+ },
+
+ /**
+ * Initializes the upload runtime. This runtime supports these features: jpgresize, pngresize, chunks.
+ *
+ * @method init
+ * @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
+ * @param {function} callback Callback to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
+ */
+ init : function(uploader, callback) {
+ var silverlightContainer, filter = '', filters = uploader.settings.filters, i, container = document.body;
+
+ // Check if Silverlight is installed, Silverlight windowless parameter doesn't work correctly on Opera so we disable it for now
+ if (!isInstalled('2.0.31005.0') || (window.opera && window.opera.buildNumber)) {
+ callback({success : false});
+ return;
+ }
+
+ initialized[uploader.id] = false;
+ uploadInstances[uploader.id] = uploader;
+
+ // Create silverlight container and insert it at an absolute position within the browse button
+ silverlightContainer = document.createElement('div');
+ silverlightContainer.id = uploader.id + '_silverlight_container';
+
+ plupload.extend(silverlightContainer.style, {
+ position : 'absolute',
+ top : '0px',
+ background : uploader.settings.shim_bgcolor || 'transparent',
+ zIndex : 99999,
+ width : '100px',
+ height : '100px',
+ overflow : 'hidden',
+ opacity : uploader.settings.shim_bgcolor || document.documentMode > 8 ? '' : 0.01 // Force transparent if bgcolor is undefined
+ });
+
+ silverlightContainer.className = 'plupload silverlight';
+
+ if (uploader.settings.container) {
+ container = document.getElementById(uploader.settings.container);
+ if (plupload.getStyle(container, 'position') === 'static') {
+ container.style.position = 'relative';
+ }
+ }
+
+ container.appendChild(silverlightContainer);
+
+ for (i = 0; i < filters.length; i++) {
+ filter += (filter != '' ? '|' : '') + filters[i].title + " | *." + filters[i].extensions.replace(/,/g, ';*.');
+ }
+
+ // Insert the Silverlight object inide the Silverlight container
+ silverlightContainer.innerHTML = '<object id="' + uploader.id + '_silverlight" data="data:application/x-silverlight," type="application/x-silverlight-2" style="outline:none;" width="1024" height="1024">' +
+ '<param name="source" value="' + uploader.settings.silverlight_xap_url + '"/>' +
+ '<param name="background" value="Transparent"/>' +
+ '<param name="windowless" value="true"/>' +
+ '<param name="enablehtmlaccess" value="true"/>' +
+ '<param name="initParams" value="id=' + uploader.id + ',filter=' + filter + ',multiselect=' + uploader.settings.multi_selection + '"/>' +
+ '</object>';
+
+ function getSilverlightObj() {
+ return document.getElementById(uploader.id + '_silverlight').content.Upload;
+ }
+
+ uploader.bind("Silverlight:Init", function() {
+ var selectedFiles, lookup = {};
+
+ // Prevent eventual reinitialization of the instance
+ if (initialized[uploader.id]) {
+ return;
+ }
+
+ initialized[uploader.id] = true;
+
+ uploader.bind("Silverlight:StartSelectFiles", function(up) {
+ selectedFiles = [];
+ });
+
+ uploader.bind("Silverlight:SelectFile", function(up, sl_id, name, size) {
+ var id;
+
+ // Store away silverlight ids
+ id = plupload.guid();
+ lookup[id] = sl_id;
+ lookup[sl_id] = id;
+
+ // Expose id, name and size
+ selectedFiles.push(new plupload.File(id, name, size));
+ });
+
+ uploader.bind("Silverlight:SelectSuccessful", function() {
+ // Trigger FilesAdded event if we added any
+ if (selectedFiles.length) {
+ uploader.trigger("FilesAdded", selectedFiles);
+ }
+ });
+
+ uploader.bind("Silverlight:UploadChunkError", function(up, file_id, chunk, chunks, message) {
+ uploader.trigger("Error", {
+ code : plupload.IO_ERROR,
+ message : 'IO Error.',
+ details : message,
+ file : up.getFile(lookup[file_id])
+ });
+ });
+
+ uploader.bind("Silverlight:UploadFileProgress", function(up, sl_id, loaded, total) {
+ var file = up.getFile(lookup[sl_id]);
+
+ if (file.status != plupload.FAILED) {
+ file.size = total;
+ file.loaded = loaded;
+
+ up.trigger('UploadProgress', file);
+ }
+ });
+
+ uploader.bind("Refresh", function(up) {
+ var browseButton, browsePos, browseSize;
+
+ browseButton = document.getElementById(up.settings.browse_button);
+ if (browseButton) {
+ browsePos = plupload.getPos(browseButton, document.getElementById(up.settings.container));
+ browseSize = plupload.getSize(browseButton);
+
+ plupload.extend(document.getElementById(up.id + '_silverlight_container').style, {
+ top : browsePos.y + 'px',
+ left : browsePos.x + 'px',
+ width : browseSize.w + 'px',
+ height : browseSize.h + 'px'
+ });
+ }
+ });
+
+ uploader.bind("Silverlight:UploadChunkSuccessful", function(up, sl_id, chunk, chunks, text) {
+ var chunkArgs, file = up.getFile(lookup[sl_id]);
+
+ chunkArgs = {
+ chunk : chunk,
+ chunks : chunks,
+ response : text
+ };
+
+ up.trigger('ChunkUploaded', file, chunkArgs);
+
+ // Stop upload if file is maked as failed
+ if (file.status != plupload.FAILED && up.state !== plupload.STOPPED) {
+ getSilverlightObj().UploadNextChunk();
+ }
+
+ // Last chunk then dispatch FileUploaded event
+ if (chunk == chunks - 1) {
+ file.status = plupload.DONE;
+
+ up.trigger('FileUploaded', file, {
+ response : text
+ });
+ }
+ });
+
+ uploader.bind("Silverlight:UploadSuccessful", function(up, sl_id, response) {
+ var file = up.getFile(lookup[sl_id]);
+
+ file.status = plupload.DONE;
+
+ up.trigger('FileUploaded', file, {
+ response : response
+ });
+ });
+
+ uploader.bind("FilesRemoved", function(up, files) {
+ var i;
+
+ for (i = 0; i < files.length; i++) {
+ getSilverlightObj().RemoveFile(lookup[files[i].id]);
+ }
+ });
+
+ uploader.bind("UploadFile", function(up, file) {
+ var settings = up.settings, resize = settings.resize || {};
+
+ getSilverlightObj().UploadFile(
+ lookup[file.id],
+ up.settings.url,
+ jsonSerialize({
+ name : file.target_name || file.name,
+ mime : plupload.mimeTypes[file.name.replace(/^.+\.([^.]+)/, '$1').toLowerCase()] || 'application/octet-stream',
+ chunk_size : settings.chunk_size,
+ image_width : resize.width,
+ image_height : resize.height,
+ image_quality : resize.quality,
+ multipart : !!settings.multipart,
+ multipart_params : settings.multipart_params || {},
+ file_data_name : settings.file_data_name,
+ headers : settings.headers
+ })
+ );
+ });
+
+ uploader.bind("CancelUpload", function() {
+ getSilverlightObj().CancelUpload();
+ });
+
+ uploader.bind('Silverlight:MouseEnter', function(up) {
+ var browseButton, hoverClass;
+
+ browseButton = document.getElementById(uploader.settings.browse_button);
+ hoverClass = up.settings.browse_button_hover;
+
+ if (browseButton && hoverClass) {
+ plupload.addClass(browseButton, hoverClass);
+ }
+ });
+
+ uploader.bind('Silverlight:MouseLeave', function(up) {
+ var browseButton, hoverClass;
+
+ browseButton = document.getElementById(uploader.settings.browse_button);
+ hoverClass = up.settings.browse_button_hover;
+
+ if (browseButton && hoverClass) {
+ plupload.removeClass(browseButton, hoverClass);
+ }
+ });
+
+ uploader.bind('Silverlight:MouseLeftButtonDown', function(up) {
+ var browseButton, activeClass;
+
+ browseButton = document.getElementById(uploader.settings.browse_button);
+ activeClass = up.settings.browse_button_active;
+
+ if (browseButton && activeClass) {
+ plupload.addClass(browseButton, activeClass);
+
+ // Make sure that browse_button has active state removed from it
+ plupload.addEvent(document.body, 'mouseup', function() {
+ plupload.removeClass(browseButton, activeClass);
+ });
+ }
+ });
+
+ uploader.bind('Sliverlight:StartSelectFiles', function(up) {
+ var browseButton, activeClass;
+
+ browseButton = document.getElementById(uploader.settings.browse_button);
+ activeClass = up.settings.browse_button_active;
+
+ if (browseButton && activeClass) {
+ plupload.removeClass(browseButton, activeClass);
+ }
+ });
+
+ uploader.bind("DisableBrowse", function(up, disabled) {
+ getSilverlightObj().DisableBrowse(disabled);
+ });
+
+ uploader.bind("Destroy", function(up) {
+ var silverlightContainer;
+
+ plupload.removeAllEvents(document.body, up.id);
+
+ delete initialized[up.id];
+ delete uploadInstances[up.id];
+
+ silverlightContainer = document.getElementById(up.id + '_silverlight_container');
+ if (silverlightContainer) {
+ silverlightContainer.parentNode.removeChild(silverlightContainer);
+ }
+ });
+
+ callback({success : true});
+ });
+ }
+ });
+})(window, document, plupload);