(57)【特許請求の範囲】
【請求項１】
ベクトル処理をサポートするプロセッサ上で各ピクセルが赤―緑―青（ＲＧＢ）画像データを備えるピクセルを含むソース画像を圧縮するための方法であって、
一連のプロセッサ命令を前記プロセッサに送信することによって前記画像をそのＲ、Ｇ、およびＢコンポーネントに分離するステップであって、８つのゼロのシーケンスを前記Ｒ、Ｇ、およびＢコンポーネントのそれぞれの８ビットの前に挿入することを含み、各プロセッサ命令は複数のピクセルのデータに同時に動作するステップと、
一連のプロセッサ命令を前記プロセッサに送信することによって前記分離された画像を輝度―オレンジ―緑（ＹＣｏＣｇ）画像データに変換するステップであって、各プロセッサ命令は複数のピクセルのデータに同時に動作するステップと、
一連のプロセッサ命令を前記プロセッサに送信することによって前記ＹＣｏＣｇ画像のＣｏおよびＣｇコンポーネントを圧縮するステップであって、各プロセッサ命令は複数のピクセルのデータに同時に動作するステップと、
前記圧縮画像データを記憶するステップと、
前記圧縮画像データのＣｏおよびＣｇコンポーネントをサブサンプリングするステップであって、
前記圧縮画像データを、４ピクセルからなる少なくとも１つのクアッドにセグメント化するステップと、
各クワッドの各行を解凍するステップと、
各クワッドの上部行と下部行とを和することによって、合わされた行を作り出すステップであって、前記上部行内のピクセルと前記下部行内のピクセルとの和が飽和値を越える時、前記上部行内のピクセルと前記下部行内のピクセルとの和を前記飽和値に設定するステップと、
各クワッドの前記合わされた行を、当該クワッドの前記合わされた行のワードシャッフルバージョンと和すステップと、
前記和して合わされた各クワッドの行を４で割るステップと、
前記和して合わされた各クワッドの行を再圧縮するステップと、
を備えるステップと、
を備えることを特徴とする方法。
【請求項２】
前記ピクセルは、それぞれが８ビットから成る４つのチャネルを備えるステップを特徴とする請求項１に記載の方法。
【請求項３】
前記Ｙコンポーネントは前記ソース画像の輝度に対応し、前記Ｃｏコンポーネントは前記ソース画像のオレンジに対応し、前記Ｃｇコンポーネントは前記ソース画像の緑に対応することを特徴とする請求項１に記載の方法。
【請求項４】
リモートデスクトッププロトコル（ＲＤＰ）プロトコル経由で前記圧縮画像データをネットワークに送信するステップをさらに備えることを特徴とする請求項１に記載の方法。
【請求項５】
ピクセルの各チャネルは８ビットを備え、前記ソース画像の各チャネルを配列することは各チャネルを１６ビット配列することを備えることを特徴とする請求項１に記載の方法。
【請求項６】
前記プロセッサは１２８ビットで同時に動作することを特徴とする請求項１に記載の方法。
【請求項７】
前記分離するステップ、前記変換するステップ、および前記記憶するステップのうちの少なくとも１つの動作は、ＳＩＭＤ命令を前記プロセッサに送信して、少なくとも１つのチャネルのそれぞれが複数のピクセルを同時に動作することを備えることを特徴とする請求項１に記載の方法。
【請求項８】
前記ソース画像は表示されるユーザセッションに対応することを特徴とする請求項１に記載の方法。
【請求項９】
前記ソース画像および前記圧縮画像データのうちの少なくとも１つは、ビットマップ画像を備えることを特徴とする請求項１に記載の方法。
【請求項１０】
前記ＣｏおよびＣｇコンポーネントを圧縮するステップは、前記画像を圧縮する量に対応する前記色損失レベルを用いて前記ＣｏおよびＣｇコンポーネントを圧縮することを備えることを特徴とする請求項１に記載の方法。
【請求項１１】
前記ＣｏおよびＣｇコンポーネントを圧縮するステップは、レンペルジフ（ＬＺ）アルゴリズムに従ってランレングス符号化を行うことを備えることを特徴とする請求項１に記載の方法。
【請求項１２】
ベクトル処理をサポートするプロセッサ上でソース画像を圧縮するためのシステムであって、
プロセッサと、
前記システムが動作可能である時に前記プロセッサと通信可能に接続され、プロセッサ実行可能命令を保持するメモリと、を備え、
前記プロセッサ実行可能命令は、前記プロセッサ上で実行されると、前記システムに少なくとも、
ピクセルを備える前記ソース画像を受信するステップであって、各ピクセルは赤―緑―青（ＲＧＢ）画像データを備えるステップと、
一連のプロセッサ命令を前記プロセッサに送信することによって前記画像をそのＲ、Ｇ、およびＢコンポーネントに分離するステップであって、８つのゼロのシーケンスを前記Ｒ、Ｇ、およびＢコンポーネントのそれぞれの８ビットの前に挿入することを含み、各プロセッサ命令は複数のピクセルのデータに同時に動作するステップと、
一連のプロセッサ命令を前記プロセッサに送信することによって前記分離された画像を輝度―オレンジ―緑（ＹＣｏＣｇ）画像データに変換するステップであって、各プロセッサ命令は複数のピクセルのデータに同時に動作するステップと、
一連のプロセッサ命令を前記プロセッサに送信することによって前記ＹＣｏＣｇ画像のＣｏおよびＣｇコンポーネントを圧縮するステップであって、各プロセッサ命令は複数のピクセルのデータに同時に動作するステップと、
前記圧縮画像データを記憶するステップと、
前記圧縮画像データのＣｏおよびＣｇコンポーネントをサブサンプリングするステップであって、
前記圧縮画像データを、４ピクセルからなる少なくとも１つのクアッドにセグメント化するステップと、
各クワッドの各行を解凍するステップと、
各クワッドの上部行と下部行とを和することによって、合わされた行を作り出すステップであって、前記上部行内のピクセルと前記下部行内のピクセルとの和が飽和値を越える時、前記上部行内のピクセルと前記下部行内のピクセルとの和を前記飽和値に設定するステップと、
各クワッドの前記合わされた行を、当該クワッドの前記合わされた行のワードシャッフルバージョンと和すステップと、
前記和して合わされた各クワッドの行を４で割るステップと、
前記和して合わされた各クワッドの行を再圧縮するステップと、
を備えるステップと、
を行わせることを特徴とする方法。
【請求項１３】
前記プロセッサ上で実行されると、少なくとも、前記圧縮画像データを４ピクセルから成る少なくとも１つのグループに分け、４ピクセルから成る各グループをサブサンプリングするステップを前記システムに行わせるプロセッサ実行可能命令を、前記メモリがさらに保持することを特徴とする請求項１２に記載のシステム。
【請求項１４】
ベクトル処理をサポートするプロセッサ上でピクセルを含むソース画像を圧縮するための、コンピュータ可読命令を備えるコンピュータ可読記憶媒体であって、
前記コンピュータ可読命令は、コンピュータ上で実行されると、前記コンピュータに、
一連のプロセッサ命令を前記プロセッサに送信することによって前記画像をそのコンポーネントカラーに分離するステップであって、８つのゼロのシーケンスを前記Ｒ、Ｇ、およびＢコンポーネントのそれぞれの８ビットの前に挿入することを含み、各プロセッサ命令は複数のピクセルのデータに同時に動作するステップと、
一連のプロセッサ命令を前記プロセッサに送信することによって前記分離された画像を第２の色空間における画像データに変換するステップであって、各プロセッサ命令は複数のピクセルのデータに同時に動作するステップと、
一連のプロセッサ命令を前記プロセッサに送信することによって前記第２の色空間における前記画像データのコンポーネントを圧縮するステップであって、各プロセッサ命令は複数のピクセルのデータに同時に動作するステップと、
前記圧縮画像データを記憶するステップと、
前記圧縮画像データの前記第２の色空間におけるコンポーネントをサブサンプリングするステップであって、
前記圧縮画像データを、４ピクセルからなる少なくとも１つのクアッドにセグメント化するステップと、
各クワッドの各行を解凍するステップと、
各クワッドの上部行と下部行とを和することによって、合わされた行を作り出すステップであって、前記上部行内のピクセルと前記下部行内のピクセルとの和が飽和値を越える時、前記上部行内のピクセルと前記下部行内のピクセルとの和を前記飽和値に設定するステップと、
各クワッドの前記合わされた行を、当該クワッドの前記合わされた行のワードシャッフルバージョンと和すステップと、
前記和して合わされた各クワッドの行を４で割るステップと、
前記和して合わされた各クワッドの行を再圧縮するステップと、
を備えるステップと、
を備える動作を行わせることを特徴とするプロセッサ。
【発明の詳細な説明】
【背景技術】
【０００１】
コンピュータは以前、独立型で他のコンピュータとのインタラクションを最小限またはほとんど行わなかったが、現在のコンピュータは、ローカルエリアネットワーク（ＬＡＮ）、ワイドエリアネットワーク（ＷＡＮ）、ダイアルアップ接続などを通じて幅広い種類のコンピュータとインタラクトする。インターネットの普及によって、コンピュータ間の接続性がますます重要になり、多くの新しいアプリケーションおよび技術が開発されている。大規模ネットワークの普及、および低コストのパーソナルコンピュータの可用性の拡大によって、多くの人々の仕事、交流（ｉｎｔｅｒａｃｔ）、通信および遊びのやり方が抜本的に変わった。
【０００２】
人気の高まっているネットワーキングの一つの形態は、一般的にバーチャルコンピューティングシステムと呼ばれ、リモートデスクトッププロトコル（ＲＤＰ）、独立型コンピューティングアーキテクチャ（ＩＣＡ）、およびデスクトップと他のアプリケーションとをリモートクライアントと共有する他のものなどのプロトコルを使用することができる。このようなコンピューティングシステムは、典型的には、クライアントからのキーボード押下およびマウスクリックまたはマウス選択をサーバに伝送して、ネットワーク接続（例えば、インターネット）を介してスクリーンの更新を反対方向に送り返す。このように、現実にはアプリケーションのスクリーンショットがサーバ側で表示される際にクライアントデバイスにそのスクリーンショットが送信されるにすぎないが、ユーザは、あたかもユーザのマシンがＬＡＮの一部として動作しているかのような体験をする。
【０００３】
ビットマップは、ネットワーク接続（例えば、インターネット）を介して伝送される時の帯域幅消費（ｂａｎｄｗｉｄｔｈ ｃｏｎｓｕｍｐｔｉｏｎ）という観点から、すべてのビットマップを送信するよりも費用がかかるために、ほとんどの仮想システムは最近、グラフィックプリミティブおよび他の動作を送信して、何をどうやって描画するかをクライアント側のサブルーチンに教える。例えば、クライアントに、矩形が描画されるべき場所、サイズ、色などについての情報に沿って矩形を描画するように教えることができる。例えば、矩形を使用して、ユーザインタフェース用の押しボタンやドキュメントの境界線を描画できる、または矩形が役立ちそうなその他の用途に使用できる。もちろん、他の形および動作も多くあり、それらをより高性能で、リモートクライアント上に転送して動作を行うのにするべきより多くの処理を要求できるプリミティブとして使用することができる。
【０００４】
アプリケーションがより高性能なグラフィカルユーザインタフェースを獲得し続けるにつれて、上記のプリミティブの使用による処理がますます増える。例えば、ビットマップ画像は、基本的に各ピクセルと関連付けられた透明度の所望のレベルを示すアルファチャネルを含むように拡張されている。この透明度レベルは、ビットマップの各ピクセルを、そのビットマップが表示されている場所にすでに存在している色と調和させる（ｂｌｅｎｄ）方法をクライアントに命令する。高性能なプリミティブの更新の処理と関連付けられた手間のさらによい例は、動画オブジェクトまたは要素であり、そこではコマンドのシーケンスは動画の各ステージにおいて動画の描画方法をクライアントに命令しなければならない。プリミティブのシーケンスが複雑すぎる時、より複雑な他のプリミティブ動作の潜在的に長いシーケンスよりはむしろ、簡素に表示することができるビットマップ表示を送信するほうが時には理にかなう場合がある。しかしながら以前に述べたように、ほとんどのビットストリーム圧縮の限界がネットワーク帯域幅を伴うために、スクリーンの完全なビットマップ表示を継続的に送信するのには費用がかかりすぎる場合がある。
【０００５】
ベクトルプロセッサとして知られるプロセッサのクラスが存在し、ベクトルプロセッサは、その命令セットアーキテクチャ（ＩＳＡ）内に単一命令複数データ（ＳＩＭＤ）命令を有する。ネハレム（商標）プロセッサのような、いくつかのインテル（商標）×８６ＩＳＡプロセッサ内のＳＳＥ４．２命令などのストリーミングＳＩＭＤ拡張命令（ＳＳＥ）は、このようなＳＩＭＤ命令の形式である。これらのプロセッサは、あるタイプのデータの高速処理が可能である。なぜならば、それらのプロセッサは、大きなデータの塊に瞬時に動作することができるからである。例えば、画像が処理される場合、ＳＩＭＤプロセッサは、単一のピクセルに一度で動作する代わりに、単一の命令と並列する数個のピクセルに動作できる。これにより命令自体を処理する性能が向上するだけでなく、メモリからデータをフェッチするのにかかる時間も短縮できる。
【０００６】
ＳＩＭＤ命令は、圧縮用画像データの処理などの、いくつかのタイプのプロセッサの性能を向上させる機会を提供するが、その処理を実装するのに必要なアルゴリズムおよび技術は、ベクトルプロセッサでないものを用いるよりもかなり難解である。データフロー、およびそれを並列で動作できる方法でデータを組織化することに対して特別な注意を払わなければならない。そのため、画像データに対する動作において並列処理を増加させる新しい技術によって利益を得るであろう。
【発明の概要】
【０００７】
本発明の実施形態は、ベクトルプロセッサ上で画像を圧縮する方法を備える。その方法は、単一の命令を６４ビットで動作する一連の動作を使用して、Ｒ、Ｇ、Ｂ、Ａ情報のそれぞれに対して各ピクセルが８ビットを備える赤−緑−青−アルファ（ＲＢＧＡ）ソース画像を必要とする。それは、各チャネルを１６ビット配列し、次にソース画像を平坦化して個々のＲ、Ｇ、Ｂベクトルを作り出す。次に、各ベクトルが解凍されて、８つのゼロを１ピクセルが８ビット値の各ベクトルの前に配置する。それは、これらの解凍ベクトルを必要とし、その解凍ベクトルをＲＧＢ色空間からＹ、ＣｏおよびＣｇベクトルを備える輝度−オレンジ−緑（ＹＣｏＣｇ）色空間に変換する。それは、次にＣｏおよびＣｇベクトルにロッシー圧縮を使用して、次に各ベクトルをランレングス符号化して最終的にソース画像の圧縮バージョンに対応する出力画像を記憶する。
【０００８】
上記および同様の処理を行うシステム、方法、およびコンピュータ可読記憶媒体が開示される。
【０００９】
本開示の１または複数のさまざまな態様は、本開示の本明細書で示す態様を達成するための回路および／またはプログラミングを含むことができるがこれに限定されず、その回路および／またはプログラミングは、システム設計者の設計上の選択に依存しながら本明細書で示す態様を達成するように構成されたハードウェア、ソフトウェア、および／またはファームウェアの実質的な任意の組み合わせとすることができることを当業者は認識することができる。
【００１０】
前述のものは概要であるので、必然的に詳細の簡略化、一般化および省略を含む。当業者は、本概要は単なる例証であり決して限定を意図するものではないことを認識するであろう。
【図面の簡単な説明】
【００１１】
【図１】本開示の態様を実装することができる例示的なコンピュータシステムを示す図である。
【図２】本開示の例示的なオペレーティングプロシージャを示す図である。
【図３】図２の動作可能なプロシージャによって作り出される出力画像をサブサンプリングするための動作可能なプロシージャを示す図である。
【発明を実施するための形態】
【００１２】
本明細書の実施形態では、ピクセル用の色チャネルを平面データソースに分割または分離することによって画像のデータ圧縮を強化するための前処理ステージまたは機構を提供する。典型的には、画像データは、画像（ビットマップなど）内の各ピクセルが色チャネルごとに１つのコンポーネントを有するように、色空間用にインタリーブされたチャネルタイプのセットとして表示される。例えば、赤、緑および青（ＲＧＢ）の色空間を有するピクセルは、赤用に１つの色チャネル、緑用に１つの色チャネル、および青用に１つの色チャネルを有する。それにより、例示的な実施形態は、同様のコンポーネントが同じ平面内で示されるように、各チャネル用のコンポーネントを平面データソースに分離する。インタリーブされたビットマップまたはデジタル画像を平面表示に分離することによって、各平面を独立して圧縮し、しばしば高い圧縮比を実現することができる。これは、特に、大抵の場合ビットマップ全体でほとんど変わらないと見込まれるチャネル（例えば、ビットマップ内の要素の透明度を記述するアルファチャネル）に当てはまる。
【００１３】
言い換えれば、例示的な実施形態は、しばしばあるチャネルが遷移され得る一方で、別のチャネルはほとんど変わらないという事実を利用する。チャネルデータの操作を通じてまたは色空間をＲＧＢのため以外の何かに変換することを通じて、上記の実施形態の利用をさらに強化することができる。例えば、照明およびクロミナンスという観点からピクセルを定義する（例えば、ＹＵＶ、ＹＣｏＣｇなど）他の色空間は、典型的には人間の目がどのように色を認識するかという観点から色空間をより多く記述する。言い換えれば、このようなタイプの色空間は、目がより敏感である色コンポーネントをその目があまり敏感でないチャネルから分離する。これによって、人間の目の知覚の違いを利用することによって、色チャネル内の情報を落として（ｄｅｇｒａｄｅ）圧縮モデルがより効率的に対処することができるパターンを強化することが可能であり、さらにその画像が知覚的にロスレスのままにすることが可能である。
【００１４】
本明細書で説明したように、圧縮比を強化するために、特定の色空間またはデジタル画像用の色情報を修正可能にするいくつかの方法があり得る。例えば、特定の色スキームのクロミナンスチャネルを、その特定のチャネルと関連付けられたすべてのビットカウントを減少させることによって量子化できることによって、その色パレットの忠実度が低下するが、必ずしも色スキームの範囲が減少するわけではない。代替的または併用して、さまざまなクロミネンス値のサンプルピクセル空間またはサブサンプリングを全体値のある平均に修正する、およびまたはその値を公分母（ｃｏｍｍｏｎ ｄｅｎｏｍｉｎａｔｏｒ）にもってくる他の同様の修正を行うことができる。以下により詳細に説明するように、圧縮用画像データを前処理する時にパターン認識を強化するようにデータを修正するための他の機構もあり得る。
【００１５】
ひとたびデジタル画像またはビットマップが論理的に分離したデジタル画像、即ちチャネル情報の各プレーン用のデジタル画像に分割される、およびひとたびデータのすべての操作または修正が行われると、例示的な実施形態は、二次元ランレングス符号化スキームなどの、標準または周知の符号化モジュールを使用してその値を符号化することができる。各走査線のビットマップを、走査線の前に置いて（ｐｒｅｃｅｄｅ）その走査線と区別して取り扱うことができ、次に、以下により詳細に説明するように、そのような区別を符号化することができる。
【００１６】
本開示の実施形態は、１または複数のコンピュータ上で実行できる。図１および以下の考察は、本開示を実装できる適切なコンピューティング環境の簡潔な概説を提供することを意図する。当業者は、図１のコンピュータシステムの一部またはすべてのコンポーネントを使用して、図３および図４のコンピュータを達成（ｅｆｆｅｃｔｕａｔｅ）することができることを認識することができる。
【００１７】
本開示を通じて使用される用語、回路は、例えば、ハードウェア割り込みコントローラ、ハードドライブ、ネットワークアダプタ、グラフィックプロセッサ、および音声コーデックなどの専用ハードウェアコンポーネント含むことができる。同じまたは他の実施形態において、回路は、ファームウェアによってまたはセットスイッチによって機能（複数可）を行うように構成されたマイクロプロセッサを含むことができる。同じまたは他の例示的な実施形態において、回路は、例えば、マルチコア汎用処理ユニットの１または複数のコアなどの、１または複数の論理プロセッサを含むことができる。この例の論理プロセッサ（複数可）を、例えば、ＲＡＭ、ＲＯＭ、ファームウェア、および／または仮想メモリなどのメモリからロードされる機能（複数可）を行うのに動作可能なロジックを実施するソフトウェア命令によって構成することができる。回路がハードウェアとソフトウェアとの組み合わせを含む例示的実施形態において、メーカー（ｉｍｐｌｅｍｅｎｔｅｒ）は、論理プロセッサによって処理することができるマシン可読コードに後でコンパイルされるロジックを実施するソースコードを書き込むことができる。当業者は、技術の最先端がハードウェア、ソフトウェア、またはハードウェア／ソフトウェアの組み合わせにおいてほとんど区別がつかない所まで進歩していることを認識することができるので、特定の機能を達成するハードウェアかソフトウェアかの選択は、メーカーに任された設計上の選択である。より詳細には、当業者は、ソフトウェア処理は同等のハードウェア構造に転換することができ、ハードウェア構造自体は同等のソフトウェア処理に転換することができることを認識することができる。従って、ハードウェア実装かソフトウェア実装かの選択は、設計上の選択の一つであり、メーカーに任される。
【００１８】
図１を参照すると、例示的な汎用コンピューティングシステムが示されている。汎用コンピューティングシステムは、１または複数の論理プロセッサ、システムメモリ２２、およびシステムメモリを含むさまざまなシステムコンポーネントを処理ユニット２１に接続するシステムバス２３を含むことができる汎用処理ユニット２１を含む、従来型コンピュータ２０などを含むことができる。システムバス２３は、メモリバスまたはメモリコントローラ、周辺バス、およびさまざまなバスアーキテクチャを任意に使用したローカルバスを含む、いくつかのタイプのバス構造のいずれにもすることができる。システムメモリは、リードオンリーメモリ（ＲＯＭ）２４およびランダムアクセスメモリ（ＲＡＭ）２５を含む。起動時などの、コンピュータ２０内の要素間で情報を転送するのに役立つ基本ルーチンを含む、基本入力／出力システム２６（ＢＩＯＳ）は、ＲＯＭ２４に記憶される。コンピュータ２０は、図示されないハードディスクの読み取りおよび書き込み用ハードディスクドライブ２７、リムーバブル磁気ディスク２９の読み取りおよび書き込み用磁気ディスクドライブ２８、およびＣＤ−ＲＯＭまたは他の光媒体などのリムーバブル光ディスク３１の読み取りおよび書き込み用光ディスクドライブ３０をさらに含むことができる。ある例示的な実施形態において、本開示の態様を実施するコンピュータ実行可能命令を、ＲＯＭ２４、ハードディスク（図示せず）、ＲＡＭ２５、リムーバブル磁気ディスク２９、光ディスク３１、および／または汎用処理ユニット２１のキャッシュに記憶できる。ハードディスクドライブ２７、磁気ディスクドライブ２８、および光ディスクドライブ３０は、ハードディスクドライブインタフェース３２、磁気ディスクドライブインタフェース３３、および光ドライブインタフェース３４によってそれぞれシステムバス２３に接続される。ドライブおよびそれらに関連付けられたコンピュータ可読媒体は、コンピュータ２０用のコンピュータ可読命令、データ構造、プログラムモジュールおよび他のデータの不揮発性記憶を提供する。本明細書で説明される例示的な環境は、ハードディスク、リムーバブル磁気ディスク２９およびリムーバブル光ディスク３１を用いるが、磁気カセット、フラッシュメモリカード、デジタルビデオディスク、ベルヌーイカートリッジ、ランダムアクセスメモリ（ＲＡＭ）、リードオンリーメモリ（ＲＯＭ）などのコンピュータによってアクセス可能なデータを記憶することができる他のタイプのコンピュータ可読媒体も例示的なオペレーティング環境に使用できることを当業者は認識されたい。
【００１９】
オペレーティングシステム３５、１または複数のアプリケーションプログラム３６、他のプログラムモジュール３７およびプログラムデータ３８を含む多数のプログラムモジュールを、ハードディスク、磁気ディスク２９、光ディスク３１、ＲＯＭ２４またはＲＡＭ２５上で記憶できる。ユーザは、キーボード４０およびポインティングデバイス４２などの入力デバイスを通じてコマンドおよび情報をコンピュータ２０に入力できる。他の入力デバイス（図示せず）は、マイクロフォン、ジョイスティック、ゲームパッド、衛星放送受信アンテナ、スキャナなどを含むことができる。これらと他の入力デバイスは、システムバスに接続されたシリアルポートインタフェース４６を通じて汎用処理ユニット２１に接続されることが多いが、パラレルポート、ゲームポートまたはユニバーサルシリアルバス（ＵＳＢ）などの他のインタフェースによっても接続できる。ディスプレイ４７または他のタイプのディスプレイデバイスも、ビデオアダプタ４８などのインタフェース経由でシステムバス２３に接続することができる。ディスプレイ４７に加えて、コンピュータは、典型的には、スピーカおよびプリンタなどの他の周辺出力デバイス（図示せず）を含む。図１の例示的なシステムは、ホストアダプタ５５、小型計算機システムインタフェース（ＳＣＳＩ）バス５６およびＳＣＳＩバス５６に接続される外部記憶デバイス６２も含む。
【００２０】
コンピュータ２０は、リモートコンピュータ４９などの、１または複数のリモートコンピュータへの論理接続を使用するネットワーク化環境において動作できる。リモートコンピュータ４９は、別のコンピュータの、サーバ、ルータ、ネットワークＰＣ、ピアデバイスまたは他の共有ネットワークノードにすることができ、メモリ記憶デバイス５０のみが図１に図示されているが。典型的には、コンピュータ２０に対して上述した要素の多くまたはすべてを含むことができる。図１に示された論理接続は、ローカルエリアネットワーク（ＬＡＮ）５１およびワイドエリアネットワーク（ＷＡＮ）５２を含むことができる。このようなネットワーキング環境は、オフィス、企業規模のコンピュータネットワーク、イントラネットおよびインターネットにおいて当たり前となっている。
【００２１】
ＬＡＮネットワーキング環境に使用される時、コンピュータ２０を、ネットワークインタフェースまたはアダプタ５３を通じてＬＡＮ５１に接続することができる。ＷＡＮネットワーキング環境に使用される時、コンピュータ２０は、典型的には、モデム５４またはインターネットなどのワイドエリアネットワーク５２に通信を確立するための他の手段を含むことができる。モデム５４は、内部モデムまたは外部モデムとしてもよく、シリアルポートインタフェース４６経由でシステムバス２３に接続することができる。ネットワーク化環境において、コンピュータ２０またはその一部に対して示されたプログラムモジュールを、リモートメモリ記憶デバイスに記憶できる。図示されたネットワーク接続は例示的であり、コンピュータ間で通信リンクを確立する他の手段も使用できることが認識されよう。さらに、本開示の多数の実施形態は、特にコンピュータ化されたシステムによく適していることが想定されるが、本文書において本開示をそのような実施形態に限定する意図はまったくない。
【００２２】
前述の詳細な説明では、例示および／または動作可能な図を介してシステムおよび／またはプロセスのさまざまな実施形態を説明した。その限りにおいてブロック図、および／または例は、１または複数の機能および／または動作を含むが、そのようなブロック図における各機能および／または動作、または例を、広範囲にわたるハードウェア、ソフトウェア、ファームウェア、またはその実質的な任意の組み合わせによって個々におよび／または集合的に実装することができることを当業者には理解されよう。
【００２３】
本明細書に説明した本発明の対象の特定の態様について説明してきたが、当業者には当然ながら、本明細書の教示に基づいて、本明細書に説明した本発明の対象およびその幅広い態様から逸脱せずに変更および修正を行うことができるので、添付の特許請求の範囲は、本明細書に説明した本発明の対象の真の精神および範囲と同様に、それらの範囲においてそのようなすべての変更および修正を網羅するものである。
【００２４】
図２は、ソース画像を、単一命令複数データ（ＳＩＭＤ）命令セットを備えるプロセッサ上で圧縮するための例示的なオペレーティングプロシージャを示している。ＳＩＭＤ命令セット用いたプロセッサは、一般にベクトルプロセッサとして知られる。ネハレム（商標）プロセッサのような、いくつかのインテル（商標）ｘ８６ＩＳＡプロセッサ内のＳＳＥ４．２命令などのストリーミングＳＩＭＤ拡張命令（ＳＳＥ）は、このようなＳＩＭＤ命令の形式である。このようなプロセッサは、並列形式でデータの大部分に瞬時に動作できる。例えば、このような６４ビットプロセッサは、２つの整数を２つの６４ビットワードにそれぞれ入れることによって、符号付き３２ビット整数の２つのセットを同時に和し、次に各６４ビットワードに加えることができる。各ローワードが２∧３１を含む場合など、通常ローワードからハイワードへオーバーフローがある場合、その命令は、一般にこれを把握し、ハイワードにオーバーフローしない。このような動作可能なプロシージャを使用して、リモートデスクトッププロトコル（ＲＤＰ）などを経由して、ネットワークに送信する画像を圧縮できる。このような実施形態において、ソース画像および出力画像は、動作するプロシージャが実行されるコンピュータにおいてローカルの場合でもユーザが体験するなどで表示されたユーザセッションに対応できる。その表示されたユーザセッションは、コンピュータデスクトップだけでなくユーザがそのコンピュータにおいて見るような方法でタイル表示された任意のオープンアプリケーションウィンドウも含むことができる。
【００２５】
実施形態において、ソース画像は、ピクセルの行および列を備え、各ピクセルは、ピクセル用の赤（Ｒ）色値、緑（Ｇ）色値、青（Ｂ）色値およびアルファ（Ａ）（または透明度）値のそれぞれに８ビットが当てられるように、ＲＧＢＡ色空間内に３２ビットを備える。
【００２６】
動作２００は、その方法から開始する。例えば、その画像を圧縮する命令に沿ってソース画像を受信すると、それを実行できる。
【００２７】
動作２０２は、ソース画像の各チャネルを１６ビット配列することを示しており、ソース画像は少なくとも１ピクセルを備え、各ピクセルは赤（Ｒ）値、緑（Ｇ）値、青（Ｂ）値およびアルファ（Ａ）値を備える。これは、そのソース画像のメモリ内の位置が１６バイトの倍数であるアドレス内にあるか確認し、次に、すべてのピクセルが８ビットであるか、次に、メモリ空間内に８ビット配列されているかを確認することを備える。
【００２８】
動作２０４は、ソース画像を平坦化してＲベクトル、ＧベクトルおよびＢベクトルを作り出すことを示しており、Ｒベクトルは各ピクセルのＲ値を備え、Ｇベクトルは各ピクセルのＧ値を備え、Ｂベクトルは各ピクセルのＢ値を備える。１番目のピクセルの赤値がＲ（１）になるようにピクセルの色値が表されている場合、ｎ個のピクセルのソース画像は、初めのうちはＲ（１）Ｇ（１）Ｂ（１）Ａ（１）Ｒ（２）Ｇ（２）Ｂ（２）Ａ（２）．．．Ｒ（ｎ）Ｇ（ｎ）Ｂ（ｎ）Ａ（ｎ）の形をとると考えることができる。ソース画像の平坦化において、そのような各ピクセルの色コンポーネントは、Ｒ（１）Ｒ（２）．．．Ｒ（ｎ）、Ｇ（１）Ｇ（２）．．．Ｇ（ｎ）、Ｂ（１）Ｂ（２）．．．Ｂ（ｎ）、Ａ（１）Ａ（２）．．．Ａ（ｎ）の形に再配列される。この再配列を作り出するための効率的なアルゴリズムは、１番目の１２８ビットの画像を４つの３２ビットピクセルを備えるようにロードすることである。次に、１番目、５番目、９番目および１３番目の８ビットセクションにＲバッファを加え、２番目、６番目、１０番目および１４番目の８ビットセクションにＧバッファを加え、３番目、７番目、１１番目および１５番目の８ビットセクションにＢバッファを加える。次に、連続する１２８ビット画像ごとにそのプロセスを繰り返す。実施形態において、Ａチャネルは平坦化されるわけでも後で使用されるわけでもなく、計算時間を節約して画像を圧縮するために廃棄される。
【００２９】
動作２０６は、Ｒベクトル、Ｇベクトル、およびＢベクトルのそれぞれを解凍して、８つのゼロのシーケンスを８ビットのベクトルの前にそれぞれ入れるようにすることを示している。ピクセルの各チャネルが８ビットを備える実施形態において、これは、２つの係数によってすべてのベクトルサイズが増加するだけでなく、２つの係数によって各ピクセルが占める有効空間（ｅｆｆｅｃｔｉｖｅ ｓｐａｃｅ）も増加する。ＲベクトルがＲ（０）Ｒ（１）．．．Ｒ（ｎ）として表されて８つのゼロのストリングが０ｘ００として表される場合、解凍ベクトルは、それらのゼロが各ピクセルの赤値の前に置かれて、０×００、Ｒ（０）、０ｘ００、Ｒ（１）、．．．０ｘ００、Ｒ（ｎ）となる。
【００３０】
動作２０８は、Ｃｏベクトルを、ＲベクトルからＢベクトルを引いた値に等しくなるように設定することを示している。実施形態において、これは、１２８ビットのＲベクトルおよびＢベクトルに一度で動作される。これは、１２８ビットのデータに一度で動作できるプロセッサへの単一の命令を用いて、１２８ビットのＲベクトルおよびＢベクトルに一度でロードして、ＲベクトルからＢベクトルを引くことを備える。ゼロを用いてベクトルが解凍された場合、各ベクトルの１２８ビットは、８ビットチャネル値を合計で６４ビット、および８つのゼロから成る８グループを別に合計６４ビット備える。ベクトルがゼロを介入して解凍されたので、オーバーフローの懸念がない。つまりどのオーバーフローもその８つのゼロのセットにあふれて次の数字まで行かない。例えば、圧縮値を０ｘ１１および０ｘ１Ｆにしてそれらが和された場合、その結果は０ｘ３０となる。しかしながら、そのような値の解凍バージョンは０ｘ０１０１および０ｘ０１０Ｆであり、その結果は０ｘ０２１０となる。右から８ビットのオーバーフローは、実データの左から８ビットになるのではなくゼロになる。この方法において同様のロジックを他の動作に適用し、特に動作２１０−２１４に適用する。
【００３１】
動作２１０は、Ｙベクトルを、等差級数的に右に１回シフトしてＢベクトルとＣｏベクトルとの和に等しくなるように設定して、次に、等差級数的に右に１回シフトしてＣｇベクトルと和されることを示している。擬似コードにおいて、この動作をＹ＝Ｂ＋（Ｃｏ＞＞１）と表すことができる。実施形態において、単一のプロセッサ命令を用いてＣｏをシフトして、それを一時的な値に記録して、次に２番目の単一のプロセッサ命令を用いてＹをＢとその一時的な値との和に設定する。実施形態において、これは、１２８ビットの各ベクトルに一度で行われる。Ｃｏが０ｘ１１１１ １１１１ １１１１ １１０１に等しく、それが右に１回シフトされたビットの場合、各ビットは右の場所に移動されて、右端のビットが廃棄されて、次に左端から２番目のビットがゼロ値を割り当てられる（左端のビットは、その数字が正の数か負の数かどうか示すのに使用されて、保存される）。こうして、０ｘ１１０１ １１１１ １１１１ １１１０が作り出される。
【００３２】
動作２１２は、Ｃｇベクトルを、ＹベクトルからＧベクトルを引いた値に等しくなるように設定することを示している。実施形態において、これは、１２８ビットの各ベクトルに一度で行われる。
【００３３】
動作２１４は、Ｙベクトルを、等差級数的に右に１回シフトしてＹベクトルをＣｇベクトルに加えた値に等しくなるように設定することを示している。実施形態において、これは、１２８ビットの各ベクトルに一度で行われる。擬似コードにおいて、この動作をＹ＝Ｙ＋（Ｃｇ＞＞１）と表すことができる。
【００３４】
１２８ビットのベクトルに一度で動作する実施形態において、その方法は、次に連続する１２８ビットの各ベクトルに対して、各ベクトルがすべてこのように操作されるまで動作２０８−２１４を繰り返す。これらの動作がすべての画像上で動作するようにループされた実施形態において、その命令は、各ループ内に２回表示される。これは、単一の動作を用いて、平坦化された１２８のベクトルがメモリ内にロードされる場合に有利である。１番目の６４ビットが解凍されて、次に動作されて、次に付加的なメモリアクセスなしで２番目の６４ビットを解凍して動作できる。すべての１２８ビットが動作される時、別のメモリアクセスが要求されてそのループが再度開始される。
【００３５】
動作２１６は、Ｃｏベクトルを、Ｃｏベクトルを色損失レベルで割った値に等しくなるように設定し、次にクロムマスクに加えられることを示している。実施形態において、色損失レベルは、各１６ビットピースのＣｏベクトルを右にシフトするために事前に決められたビット数であり（上記のように、値が符号化される場合に符号を保存する）、画像を圧縮する量に対応する。これによって、色情報の精度がいくらか低下する（最も重要でないビットが廃棄される）だけでなく、さらに多くのピクセルが同じ色値を有するので画像が最終的に圧縮され得る量も増加する（ランレングス符号化アルゴリズムの有効性が増加する）。同様に、クロムマスクは、クロム損失レベルによって１６ビットごとをビット単位にして右にシフトされる１２８のセットを表す。クロムマスクレベルの和において、１番目のレベルの圧縮が行われる。
【００３６】
動作２１８は、Ｃｇベクトルを、Ｃｇベクトルを色損失レベルで割った値に等しくなるように設定し、次にクロムマスクに加えられることを示している。実施形態において、色損失レベルは、各１６ビットピースのＣｏベクトルを右にシフトするために事前に決められたビット数であり（上記のように、値が符号化される場合に符号を保存する）。これによって、色情報の精度がいくらか低下する（最も重要でないビットが廃棄される）だけでなく、さらに多くのピクセルが同じ色値を有するので画像が最終的に圧縮され得る量も増加する（ランレングス符号化アルゴリズムの有効性が増加する）。同様に、クロムマスクは、クロム損失レベルによって１６ビットごとをビット単位にして右にシフトされる１２８のセットを表す。クロムマスクレベルの和において、１番目のレベルの圧縮が行われる。実施形態において、クロムマスクは２進数列を備え、それらは、ピクセルの赤値のビット数の２倍に対応するビットグループ内の色損失レベルによって右にシフトされたビットを、プロセッサが同時に等差級数的に動作できるビット数に等しい。
【００３７】
動作２２０は、ＣｏおよびＣｇベクトルをサブサンプリングする任意のステップを示している。これを、例えば、いくつかの隣接ピクセルの色値を平均化して、その平均値を各ピクセルの色値に割り当てることによって完了できる。これによって、多くの値が反復されるので、圧縮アルゴリズムが出力画像となる記憶空間をさらに削減することが可能になるであろう。図３の考察においてこの動作の実施形態のさらなる詳細が与えられる。
【００３８】
動作２２２は、Ｙベクトルをランレングス符号化することを示している。実施形態において、Ｙベクトルは、他の２つのベクトルが動作２１６および２１８で行われるように圧縮される。これは、人間の目がＹベクトルで表される輝度に最も敏感であるので、この情報を保存する際、人間は他の２つのチャネルに対するロッシー圧縮があまり目立たないと思うであろう。ランレングス符号化は、同じデータ値が単回に分かれて連続したデータ値を、その回数によって表されるデータ値の数をカウントしながら記憶することによってベクトルを圧縮することを備えるロスレス圧縮スキームである。例えば、文字ストリングＡＡＡＡＡＡＡＢＢＢＢＡＡＡＡＡがあるとして、このストリングのランレングスの符号化バージョンを（Ａ７）（Ｂ３）（Ａ５）と表現できる。実施形態において、このランレングス符号化は、レンペルジフ（ＬＺ）アルゴリズムに従って行われる。ＬＺアルゴリズムは、典型的には、圧縮されるオブジェクトとＬＺアルゴリズムによって保持されるデータ構造（しばしば辞書と呼ばれる）内に含まれるストリングのセットとの間で一致を検索することによって動作する。ＬＺアルゴリズムが一致を見つける時、それは、データ構造内の一致する位置の参照と一致自体とを置き換える。実施形態において、他のランレングス符号化技術を使用して、反復実行を探して、そしてその反復実行を、反復される連長およびバイトパターンを表示するコードと置き換える順方向検索を行うことができる。実施形態において、二次元ランレングス符号化技術は、圧縮効率を高めるのに使用される。これは、ランレングス符号化をさらに容易にすることができる垂直反復が存在するゼロの「垂直」ストリップを実現するために、現在のピクセル行と以前のピクセル行との排他的論理和（ＸＯＲ‘ｉｎｇ）によって実現される。
【００３９】
動作２２４は、Ｃｏベクトルをランレングス符号化することを示している。この符号化形態は、ごくわずかの異なるタイプの色を使用する画像上で最も効果がある（色調または色相の非常にわずかな変化であってもランレングス符号化の付加的な記憶空間を要求する）ので、その技術には、上記のベクトルに適用されるクロマ損失レベルが有効である。
【００４０】
動作２２６は、Ｃｇベクトルをランレングス符号化することを示している。これを、動作２２２または２２４と同様にして行うことができる。
【００４１】
動作２２８は、出力画像の記憶を示しており、その出力画像はＹベクトル、ＣｏベクトルおよびＣｇベクトルを備え、その出力画像はそのソース画像に対応する。実施形態において、これは、ＹＣｏＣｇ画像を非平坦化することを備える。実施形態において、記憶は、ＲＡＭなどのメモリに記憶して、次にクライアントによって使用されるリモートデスクトッププロトコル（ＲＤＰ）に従ってコンピュータネットワークに画像を伝送することを備える。
【００４２】
図３は、図２の動作可能なプロシージャによって作り出されるような出力画像をサブサンプリングするための動作可能なプロシージャを示している。それを図２の動作２２０の実施形態とすることができる。
【００４３】
動作３０２は、出力画像を少なくとも１クアッド（ｑｕａｄ）にセグメント化するステップを示しており、クアッドは、クアッド内の各ピクセルが出力画像の列をそのクアッド内のもう１つのピクセルと共有およびクアッド内の各ピクセルが出力画像の行をそのクアッド内のもう１つのピクセルと共有できるように４ピクセルを備え、各クワッドは、上部行（ｔｏｐ ｒｏｗ）および下部行（ｂｏｔｔｏｍ ｒｏｗ）を有し、しかもピクセルは最大でも１クワッドしか対応しない。この実施形態において、画像をサブサンプリングすることによってさらなる圧縮が生成され、ＣｏおよびＣｇベクトルをランレングス符号化する前に、圧縮を高めるための画像の前処理を行うことできる。このような動作は、（画像忠実度の損失において）ピクセルによって表される色値の均一性を高めるので、ランレングス符号化を使用した圧縮の増加が可能になる。
【００４４】
動作３０４は、各クワッドの各行を１６ビット値に解凍して、各行をゼロで配置するステップを示している。ピクセルの各チャネルが８ビットを備える実施形態において、これは、２つの係数によってすべてのベクトルサイズが増加するだけでなく、２つの係数によって各ピクセルが占める有効空間も増加する。ＲベクトルがＲ（０）Ｒ（１）．．．Ｒ（ｎ）として表されて８つのゼロのストリングが０ｘ００として表される場合、解凍ベクトルは、それらのゼロが各ピクセルの赤値の前に置かれて、０ｘ００、Ｒ（０）、０ｘ００、Ｒ（１）、．．．０ｘ００、Ｒ（ｎ）となる。
【００４５】
動作３０６は、各クワッドの上部行と下部行とを和して合わされた行を作り出すステップを示しており、そこでは各行内の各ピクセルが飽和値を有していて、上部行内のピクセルと下部行内のピクセルとの和が飽和値を越える時、上部行内のピクセルと下部行内のピクセルとの和をその飽和値に設定する。つまり、ピクセルの各チャネルが８ビットの情報を備えていて、そのチャネルの値が８ビットの符号なし整数として表されている場合、そのチャネルが有し得る最大値は、２＾８−１すなわち２５５である。この２５５は、それより大きい値を記憶できないので、この例での飽和値である。２つの数字の和が２５５を超えるようでも、その和は２５５に設定される。つまり、１００と１５０との和は、合わせて２５０の値を有する行になるが、通常３５０になるであろう１００と２５０との和は、飽和値に限定され、その合わされた行は２５５の値を有する。この動作は、動作２３４−２３８と同様に画像のサブサンプリング部を備えることができる。
【００４６】
動作３０８は、合わされた各クワッドの行を、合わされたそのクワッドの行のワードシャッフルバージョン（ｗｏｒｄ−ｓｈｕｆｆｌｅｄ ｖｅｒｓｉｏｎ）と和すステップを示している。行を左から右にピクセル値０、１、２、３として表し得る場合、最初の２つの値が入れ替わることおよび最後の２つの値が入れ替わることによって、行１、０、３、２が作り出される。これは、次に、元行（ｏｒｉｇｉｎａｌ ｒｏｗ）に加えられて、０＋１、１＋０、２＋３、３＋２の値を作り出す。そこで、最初の２つの値が互いに等しいおよび２番目の値が互いに等しいので、それらを冗長として無視できる。
【００４７】
動作３１０は、和して合わされた各クワッドの行を４で割るステップを示している。実施形態において、これは、２つの行の場所を等差級数的に右にシフトすることによって完了する。実施形態において、これは、１２８ビットの各ベクトルに一度で行われ、そのシフトは、上記の等差級数的シフティングの考察と同様に、１２８ビットストリングの４つの３２ビット部で個々に発生する。４で割ることによって、クワッドの平均値が決定される。平均値を使用する際、ロッシー圧縮が実現される。４つの係数によって精度が低下するが、記憶される１つの値がクワッド内の４つのすべてのピクセルに対応するので、以前と比較してわずか４分の１の値を記憶すればよい。実施形態において、現在のクワッド内の冗長値は廃棄される。
【００４８】
動作３１２は、和して合わされた各クワッドの行を再圧縮するステップを示している。
実施形態において、これは、解凍動作と同類（ｓｉｂｌｉｎｇ）である。つまり、その解凍動作中に導入された８つのゼロのグループを廃棄する。
【００４９】
＜サンプルコード＞
以下は、ハイレベルなＣ言語プログラミングのシンタックスにおけるサンプル擬似コードを備え、ベクトルプロセッサ上で実行される時、図２の詳細な説明で説明したのと同様に本開示の実施形態の方法において、ソース画像“ｓｒｃＩｍａｇｅ”に動作する。
【００５０】
ULONG
NSTestCompress(
NSBitmap&   srcImage,
PBYTE          pOutputBuf,
ULONG         cbMaxOutbufSize,
PBYTE           pYBuffer,
PBYTE           pCoBuffer,
PBYTE           pCgBuffer, 
ULONG          cbPlaneOutputSize,
PBYTE           pWorkBuf,
ULONG          cbWorkBuf)
{
BOOL bSubSample = NS_SUBSAMPLE;
// We operate 4 pixels at a time
//
//  P0 = R0G0B0A0
//  P1 = R1G1B1A1
//  P2 = R2G2B2A2
//  P3 = R3G3B3A3  
//
//  First we planarize as follows using CPU
//  Rn = R0R1R2R3
//  Gn = G0G1G2G3
//  Gn
//
//
//
// 16-byte align the output buffer
pYBuffer = (PBYTE)(XROUND_UP_16((ULONG)pYBuffer));
pCoBuffer = (PBYTE)(XROUND_UP_16((ULONG)pCoBuffer));
pCgBuffer = (PBYTE)(XROUND_UP_16((ULONG)pCgBuffer));
PBYTE pYBufferOrig = pYBuffer;
PBYTE pCoBufferOrig = pCoBuffer;    
PBYTE pCgBufferOrig = pCgBuffer;        
//
// 1) Prep the data by splitting planes
//
PBYTE   pRbuffer, pGbuffer, pBbuffer;
//
// 16-byte align channels for SSE perf
//
ULONG cbColorChannelSpace = XROUND_UP_16(srcImage._height * srcImage._width);
if (cbColorChannelSpace * 3 > cbWorkBuf) {
return 0;
}
pRbuffer = pWorkBuf;
pGbuffer = pRbuffer + cbColorChannelSpace;
pBbuffer  = pGbuffer + cbColorChannelSpace;
PBYTE pSrcPixel;
PBYTE pEndPixel;
ULONG* pRBufferDWORD = (ULONG*)XROUND_UP_16((ULONG)pRbuffer);
ULONG* pGBufferDWORD = (ULONG*)XROUND_UP_16((ULONG)pGbuffer);
ULONG* pBBufferDWORD = (ULONG*)XROUND_UP_16((ULONG)pBbuffer);
//
// 1) PLANARIZE - EFFICIENT
//
pSrcPixel = srcImage._pImgBits;
pEndPixel = pSrcPixel + srcImage._height* srcImage._stride;
while (pSrcPixel < pEndPixel) {
*pRBufferDWORD++ = X_MAKE_DWORD(pSrcPixel[0], pSrcPixel[4], pSrcPixel[8], pSrcPixel[12]);
*pGBufferDWORD++ = X_MAKE_DWORD(pSrcPixel[1+0], pSrcPixel[1+4], pSrcPixel[1+8], pSrcPixel[1+12]);            
*pBBufferDWORD++ = X_MAKE_DWORD(pSrcPixel[2+0], pSrcPixel[2+4], pSrcPixel[2+8], pSrcPixel[2+12]);                        
【００５１】
pSrcPixel+=16;
}
//
// 2 Compute Y Coefficients
//
__m128i xmmZero = _mm_setzero_si128();
__m128i xmmRvect, xmmGvect, xmmBvect;
__m128i xmmYFirstQWORD, xmmCoFirstQWORD;
PBYTE pRbufferReader = pRbuffer;
PBYTE pGbufferReader = pGbuffer;
PBYTE pBbufferReader = pBbuffer;    
PBYTE pBbufferReaderEnd = (pRbuffer + cbColorChannelSpace); 
__m128i xmm1, xmm2, xmm3, xmmCo, xmmY, xmmCg;
__m128i xmmCo2, xmmY2, xmmCg2;
__m128i xmmChromaMask = _mm_set_epi16(0x1ff >> X_COLOR_LOSS_LEVEL,
0x1ff >> X_COLOR_LOSS_LEVEL,
0x1ff >> X_COLOR_LOSS_LEVEL,
0x1ff >> X_COLOR_LOSS_LEVEL,
0x1ff >> X_COLOR_LOSS_LEVEL,
0x1ff >> X_COLOR_LOSS_LEVEL,
0x1ff >> X_COLOR_LOSS_LEVEL,
0x1ff >> X_COLOR_LOSS_LEVEL);                             
while (pRbufferReader < pBbufferReaderEnd) {
//
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  First 64-bits in parallel
//
//
// Read color vectors
//
xmmRvect = _mm_loadl_epi64((__m128i*)pRbufferReader);
xmmGvect = _mm_loadl_epi64((__m128i*)pGbufferReader);
xmmBvect = _mm_loadl_epi64((__m128i*)pBbufferReader);
pRbufferReader += 8;
pGbufferReader += 8;
pBbufferReader += 8;        
// unpack to R 0 G 0 B 0 (16 bits per channel to make math per 
//16 bit possible)
xmmRvect = _mm_unpacklo_epi8(xmmRvect, xmmZero);
xmmGvect = _mm_unpacklo_epi8(xmmGvect, xmmZero);    
xmmBvect = _mm_unpacklo_epi8(xmmBvect, xmmZero);        i
//  NOTE 3
//    co  = r - b;
//    y   = b + (co >> 1);
//   cg  = g - y;
//    y  += (cg >> 1);        
xmmCo  = _mm_subs_epi16(xmmRvect, xmmBvect);// co = R - B
xmm1    = _mm_srai_epi16(xmmCo, 1);         // co >> 1
xmmY    = _mm_adds_epi16(xmmBvect, xmm1);   // y = b + co >> 1
xmmCg  = _mm_subs_epi16(xmmGvect, xmmY);    // cg = g - y
xmm1    = _mm_srai_epi16(xmmCg, 1);         // cg >> 1
xmmY    = _mm_adds_epi16(xmmY, xmm1);       // y += cg >> 1
// Now do masks on Co and Cg
xmmCo = _mm_srai_epi16(xmmCo, X_COLOR_LOSS_LEVEL);
xmmCo = _mm_and_si128(xmmCo, xmmChromaMask);
xmmCg = _mm_srai_epi16(xmmCg, X_COLOR_LOSS_LEVEL);
xmmCg = _mm_and_si128(xmmCg, xmmChromaMask);        
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Second 64-bits
//
//
【００５２】
// Read color vectors
//
xmmRvect = _mm_loadl_epi64((__m128i*)pRbufferReader);
xmmGvect = _mm_loadl_epi64((__m128i*)pGbufferReader);
xmmBvect = _mm_loadl_epi64((__m128i*)pBbufferReader);
pRbufferReader += 8;
pGbufferReader += 8;
pBbufferReader += 8;        
// unpack to R 0 G 0 B 0 (16 bits per channel to make math per   
//16 bit possible)
xmmRvect = _mm_unpacklo_epi8(xmmRvect, xmmZero);
xmmGvect = _mm_unpacklo_epi8(xmmGvect, xmmZero);    
xmmBvect = _mm_unpacklo_epi8(xmmBvect, xmmZero);        
//
//    co  = r - b;
//    y   = b + (co >> 1);
//   cg  = g - y;
//    y  += (cg >> 1);        
xmmCo2  = _mm_subs_epi16(xmmRvect, xmmBvect);// co = R - B
xmm1    = _mm_srai_epi16(xmmCo2, 1);         // co >> 1
xmmY2    = _mm_adds_epi16(xmmBvect, xmm1);   // y = b + co >> 1
xmmCg2  = _mm_subs_epi16(xmmGvect, xmmY2);   // cg = g - y
xmm1    = _mm_srai_epi16(xmmCg2, 1);         // cg >> 1
xmmY2    = _mm_adds_epi16(xmmY2, xmm1);      // y += cg >> 1
// Now do masks on Co and Cg
xmmCo2 = _mm_srai_epi16(xmmCo2, X_COLOR_LOSS_LEVEL);
xmmCo2 = _mm_and_si128(xmmCo2, xmmChromaMask);
xmmCg2 = _mm_srai_epi16(xmmCg2, X_COLOR_LOSS_LEVEL);
xmmCg2 = _mm_and_si128(xmmCg2, xmmChromaMask);        
//
// Now do storage
//
// Y component - pack into 16-bytes
xmmY = _mm_packs_epi16(xmmY, xmmY2); 
_mm_store_si128((__m128i*)pYBuffer, xmmY);  //stores in one shot
pYBuffer += 16; 
// Co component - pack into 16-bytes
xmmCo = _mm_packs_epi16(xmmCo, xmmCo2); 
_mm_store_si128((__m128i*)pCoBuffer, xmmCo);
pCoBuffer += 16;         
// Cg component - pack into 16-bytes
xmmCg = _mm_packs_epi16(xmmCg, xmmCg2); 
_mm_store_si128((__m128i*)pCgBuffer, xmmCg);
pCgBuffer += 16;         
}
//
// Now do the ACRUSH magic on each channel!;
//
ULONG retVal;
if (!g_pACContext) {
g_cbACContextSize = RDPCompress_GetContextSize(PACKET_COMPR_TYPE_ACRUSH);
g_pACContext = malloc(g_cbACContextSize);
RDPCompress_InitSendContext(g_pACContext, g_cbACContextSize, PACKET_COMPR_TYPE_ACRUSH);
}
ULONG   cbCompressedSize;
ULONG   cbOrigSize;
//
// Do Y Channel
//
cbCompressedSize = cbColorChannelSpace;
ULONG   cbOutSizeTotal = 0;
PBYTE          pCurWriteOutput = pOutputBuf;
//
// ~~~~~~~~~~~~~~~~~~ Y component ~~~~~~~~~~~~~
//
【００５３】
retVal = XRDPCompress(PACKET_COMPR_TYPE_ACRUSH,
pYBufferOrig,
pCurWriteOutput,
&cbCompressedSize,
g_pACContext);
///    printf("Y: run=%d compr=%d\n", cbRunLength, cbCompressedSize);     
if (retVal & PACKET_COMPRESSED) {
cbOutSizeTotal += cbCompressedSize;
}
else {
memcpy(pCurWriteOutput, pYBufferOrig, cbColorChannelSpace);
cbOutSizeTotal += cbColorChannelSpace;
}
pCurWriteOutput += cbOutSizeTotal;
//
// ~~~~~~~~~~~~~~~~~~ Co component ~~~~~~~~~~~~~ 
//
//
// Downsample CO
//
if (bSubSample) {
ULONG cbSubSampleSize;
cbSubSampleSize = NSSubSample2xColorChannelSSE(pCoBufferOrig, cbColorChannelSpace, srcImage._width, srcImage._height,
pWorkBuf, cbWorkBuf);
pCoBufferOrig = pWorkBuf;
cbCompressedSize = cbSubSampleSize;
}
else {
cbCompressedSize = cbColorChannelSpace;
}
retVal = XRDPCompress(PACKET_COMPR_TYPE_ACRUSH,
pCoBufferOrig,
pCurWriteOutput,
&cbCompressedSize,
g_pACContext);
if (retVal & PACKET_COMPRESSED) {
cbOutSizeTotal += cbCompressedSize;
}
else {
memcpy(pCurWriteOutput, pCoBufferOrig, cbColorChannelSpace);
cbOutSizeTotal += cbColorChannelSpace;
}
pCurWriteOutput += cbCompressedSize;
//
// ~~~~~~~~~~~~~~~~~~ Cg component ~~~~~~~~~~~~~  //exactly same as Co
//
// Downsample CO
//
if (bSubSample) {
ULONG cbSubSampleSize;
cbSubSampleSize = NSSubSample2xColorChannelSSE(pCgBufferOrig, cbColorChannelSpace, srcImage._width, srcImage._height,
pWorkBuf, cbWorkBuf);
pCgBufferOrig = pWorkBuf;
cbCompressedSize = cbSubSampleSize;
}
else {
cbCompressedSize = cbColorChannelSpace;
【００５４】
}
retVal = XRDPCompress(PACKET_COMPR_TYPE_ACRUSH,
pCgBufferOrig,
pCurWriteOutput,
&cbCompressedSize,
g_pACContext);
if (retVal & PACKET_COMPRESSED) {
cbOutSizeTotal += cbCompressedSize;
}
else {
memcpy(pCurWriteOutput, pCgBufferOrig, cbColorChannelSpace);
cbOutSizeTotal += cbColorChannelSpace;
}
pCurWriteOutput += cbCompressedSize;
return cbOutSizeTotal;
}
【００５５】
以下は、ハイレベルなＣ言語プログラミングのシンタックスにおけるサンプル擬似コードを備え、ベクトルプロセッサ上で実行される時、図３の詳細な説明で説明したのと同様に本開示の実施形態の方法において、パラメータＮＳＳｕｂＳａｍｐｌｅ２ｘＣｏｌｏｒＣｈａｎｎｅｌＳＳＥ（）によって定義された画像に動作する。
【００５６】
ULONG
NSSubSample2xColorChannelSSE(
PBYTE       pSrcBytes,
ULONG      cbLength,
ULONG      width,
ULONG      height,
PBYTE       pOutputBytes,
ULONG      cbMaxOutputLen
)
{
PBYTE   pEndData       = pSrcBytes + width*height;
__m128i xmmZero = _mm_setzero_si128();    
ULONG*  pOutputWriter = (ULONG*)pOutputBytes;
//
// Fix fix no uniform row
//
for (ULONG i=0; i<height-1; i++) {
PBYTE   pCurrentRow = pSrcBytes + width * i;
PBYTE   pRowEnd = pCurrentRow + width;
__m128i srcDataRow0;
__m128i xmm1;
__m128i srcDataRow1;
while (pCurrentRow < pRowEnd) {
srcDataRow0 = _mm_loadl_epi64((__m128i*)pCurrentRow);
srcDataRow1 = _mm_loadl_epi64((__m128i*)(pCurrentRow+width));
pCurrentRow += 8;
//
// Unpack to 16-bit values  
//
srcDataRow0 = _mm_unpacklo_epi8(srcDataRow0, xmmZero);
srcDataRow1 = _mm_unpacklo_epi8(srcDataRow1, xmmZero);        
//
// Add with saturate row1+row2
//
srcDataRow0 = _mm_adds_epi16(srcDataRow0, srcDataRow1);
//
//make a copy shuffled to swap each WORD
//
【００５７】
xmm1 = _mm_shufflehi_epi16(srcDataRow0, _MM_SHUFFLE(2,3,0,1));  
xmm1 = _mm_shufflelo_epi16(srcDataRow0, _MM_SHUFFLE(2,3,0,1));            
//
// Now add the alternating cols
//
xmm1 = _mm_adds_epi16(xmm1, srcDataRow0);
xmm1 = _mm_srai_epi16(xmm1, 2);
xmm1 = _mm_shufflehi_epi16(xmm1, _MM_SHUFFLE(3,1,2,0));      
xmm1 = _mm_shufflelo_epi16(xmm1, _MM_SHUFFLE(3,1,2,0));      
// bring together the unique values in the 2-LOWDWORDS 
xmm1 = _mm_shuffle_epi32(xmm1, _MM_SHUFFLE(3,1,2,0));        
//
// We now have
//      (P00+P01+P10+P11) (P00+P01+P10+P11)    
//       (P02+P03+P12+P13)(P02+P03+P12+P13)
// net every other 16-bit value is redundant - pack away now
//
xmm1 = _mm_packs_epi16(xmm1, xmmZero); 
// low 4 bytes are the averages we want 
*pOutputWriter++ = *((ULONG*)&xmm1);
}
}
return   cbLength / 4;
}
【図１】
0005968384.tif 000002
【図２】
0005968384.tif 000003
【図３】
0005968384.tif 000004