2019年7月28日日曜日

SQL で MP4 をパース

SQL でビットマップ画像の2値化は4年位前に挑戦した。
最近、それの Impala 版 を作ったときに閃いた。
「再帰CTEがあるなら、mp4 もいけるんじゃないか」と。
やってみた。

use ragingo

drop table video
go

create table video (
    type varchar(max) not null,
    data varbinary(max) not null
)
go

insert into video(type, data)
select
    'mp4' as type,
    BulkColumn as data
from
    openrowset(bulk N'D:\temp\videos\dst.mp4', SINGLE_BLOB) as video_data
go

drop synonym dbo.read_bytes
go

create synonym read_bytes for master.dbo.fn_varbintohexsubstring
go


with
    parse_boxes(size, type, current_offset, next_offset, data) as (
        select
            convert(int, convert(varbinary(max), dbo.read_bytes(1, data, 1, 4), 1)),
            convert(varchar(max), convert(varbinary(max), dbo.read_bytes(1, data, 1 + 4, 4), 1)),
            1,
            convert(int, convert(varbinary(max), dbo.read_bytes(1, data, 1, 4), 1)) + 1,
            data
        from
            video
        union all
        select
            convert(int, convert(varbinary(max), dbo.read_bytes(1, data, next_offset, 4), 1)),
            convert(varchar(max), convert(varbinary(max), dbo.read_bytes(1, data, next_offset + 4, 4), 1)),
            next_offset,
            (case convert(varchar(max), convert(varbinary(max), dbo.read_bytes(1, data, next_offset + 4, 4), 1))
                -- box      : 4 + 4 (size + type)
                -- full box : 4 + 4 + 4 (box + version 8bit + flag 24bit)
                when 'moov' then 4 + 4
                when 'trak' then 4 + 4
                when 'edts' then 4 + 4
                when 'mdia' then 4 + 4
                when 'minf' then 4 + 4
                when 'dinf' then 4 + 4
                when 'dref' then 4 + 4 + 4 + 4 -- data reference box : full box + 4 (entry count)
                when 'stbl' then 4 + 4
                when 'stsd' then 4 + 4 + 4 + 4 -- sample description box : full box + 4 (entry count)
                when 'udta' then 4 + 4
                when 'meta' then 4 + 4 + 4
                else convert(int, convert(varbinary(max), dbo.read_bytes(1, data, next_offset, 4), 1))
            end) + next_offset,
            data
        from
            parse_boxes
        where
            size is not null
    ),
    parse_avc1(size, type, current_offset, next_offset, data, width, height) as (
        select
            size,
            type,
            current_offset,
            next_offset,
            data,
            -- sample entry (6 + 2) + visual sample entry (2 + 2 + 4 * 3 + 2 (w) + 2 (h))
            convert(int, convert(varbinary(max), dbo.read_bytes(1, data, current_offset + 4 + 4 + 6 + 2 + 2 + 2 + 4 * 3, 2), 1)),
            convert(int, convert(varbinary(max), dbo.read_bytes(1, data, current_offset + 4 + 4 + 6 + 2 + 2 + 2 + 4 * 3 + 2, 2), 1))
        from
            parse_boxes
        where
            type = 'avc1'
    ),
    dump as (
        select
            size,
            type,
            current_offset - 1 as current_offset,
            next_offset - 1 as next_offset
        from
            parse_boxes
    )
select
    *
from
    dump
option (maxrecursion 100)
実行結果


2017年4月9日日曜日

メモ
Windows 10 Creators Update を入れた後、ストアが起動できなくなった

試行錯誤
・WSReset
・隠しフォルダにある一時ファイルを削除
・日時や言語を見直し
・再起動
・設定>アプリ>Store>詳細オプション に リセットボタンがあるから押す
→ アプリ名が"Store" から"ストア"に変わった。起動できるようになった。
→ Calendar と Calculator もおかしい。リセット前は起動できなかったが、リセットしたら起動できた。

2016年12月5日月曜日

持ち運び便利なシェーダー練習帳

HTML1枚にぎゅっと詰まったシェーダー練習帳

gist
https://gist.github.com/ragingo/e9edf399419dd90bd2894de9f48f6710


フラグメントシェーダーが終わったら、
今度は頂点シェーダーをやろう。

2016年11月22日火曜日

Hyper-V error 32788

Hyper-V の 仮想マシン起動時のエラー 32788 に苦しめられたけど、イベントログ見れば一瞬で解決できたのでメモ

イベントビューアー > アプリケーションとサービスログ > Microsoft > Windows > Hyper-V-****

今回は、「RemoteFX Manager プロセスを開始できませんでした」とあったから、「RemoteFx 3D ビデオ アダプター」を仮想マシンの設定から削除した。

2016年8月20日土曜日

Windows 版 iTunes のアップデートが失敗する事について調べた


1. まず 「windows itunes サーバーが見つからない」 で検索

2. https://discussionsjapan.apple.com/thread/10171836?start=0&tstart=0 がヒット

3. インターネットオプション「暗号化されたページをディスクに保存しない」 をオフにすると解決する事を知る

4. PowerShellスクリプトか何かをダブルクリックするだけで設定を切り替えたいから、インターネットオプションの「適用」ボタンを押した時に何が起こっているのかを調べる

5. Sysinternals Process Monitor を起動し、プロセス名でフィルタしてみる

6. 「Path」からそれっぽいのを探すと、「DisableCachingOfSSLPages」が見つかる

7. その行を選択してフィルタに追加する

8. チェックボックスを切り替えて「適用ボタン」を押す、という操作を繰り返す

9. 「DisableCachingOfSSLPages」で合ってた

10. 後はこれの値を更新するスクリプトを書くだけ


2016年2月14日日曜日

Windows Phone IP over USB Transport (IpOverUsbSvc) について

サービス「Windows Phone IP over USB Transport (IpOverUsbSvc)」が無いのに気づいた時点での開発環境
・Windows 7 -> Windows 10 へのアップグレード
・VS2010, VS2013, VS2015 インストール済み
・Windows Phone に関するもの(SDK等)はインストールした記憶無し

調べた結果
・Windows Phone SDK 8.0 をインストールする必要があった

疑問
・Windows 10 Mobile なのになんで Windows Phone SDK 8.0 をわざわざ入れないといけないのか

メモ
・Windows Phone SDK 8.0 のせいで無駄にSSDを4GBも使われた
・Windows Phone SDK 8.0 インストール完了時点で VS2012 が無いから幾つかエラーが表示されていた

2015年9月2日水曜日

SQLで画像処理(2値化)

以前やったSQLでの画像処理(2値化)です。
master.dbo.fn_varbintohexsubstring が遅すぎるから、そこだけ c# で対応しました。

処理前

処理後(SSMS -> Excel)

use sample
go

------------------------------------
-- 入力画像データ格納テーブル
------------------------------------
/*
create table image_data(
    id int not null identity(1,1) constraint PK_image_data primary key,
    name varchar(100),
    data varbinary(max)
)
go
*/

-- C:\Windows\Web\Wallpaper\Theme1\smile1.jpg -> D:\dev\data\smile1.bmp

------------------------------------
-- 画像登録
------------------------------------
/*
insert into image_data(name, data)
select
    'smile1_24_192_120',
    (select * from openrowset(bulk N'D:\dev\data\smile1.bmp', SINGLE_BLOB) as bin)
go
*/

------------------------------------
-- 出力画像データ格納テーブル
------------------------------------
/*
create table result_image(
    pos int not null,
    row_index int not null,
    col_index int not null,
    pix int not null,
    constraint PK_result_image_rowcol primary key(row_index, col_index)
)
*/

------------------------------------
-- 前処理
------------------------------------
truncate table result_image
go

------------------------------------
-- ビットマップ情報取得
------------------------------------
with
    ------------------------------------
    -- 固定パラメータ
    ------------------------------------
    Param as (
        select name, convert(varchar(max), data, 2) as data, data as rawdata from image_data where name = 'smile1_24_192_120'
    ),
    ------------------------------------
    -- ビットマップファイルヘッダ
    ------------------------------------
    BITMAPFILEHEADER as (
        select
            convert(char(2), dbo.Collection_Range(p.rawdata, 0, 2)) as bfType,
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata,  2, 4))) as bfSize,
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata,  6, 2))) as bfReserved1,
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata,  8, 2))) as bfReserved2,
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, 10, 4))) as bfOffBits
        from
            Param as p
    ),
    ------------------------------------
    -- ビットマップ情報ヘッダ
    ------------------------------------
    BITMAPINFOHEADER as (
        select
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, 14, 4))) as biSize,
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, 18, 4))) as biWidth,
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, 22, 4))) as biHeight,
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, 26, 2))) as biPlanes,
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, 28, 2))) as biBitCount,
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, 30, 4))) as biCopmression,
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, 34, 4))) as biSizeImage,
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, 38, 4))) as biXPixPerMeter,
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, 42, 4))) as biYPixPerMeter,
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, 46, 4))) as biClrUsed,
            convert(int, dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, 50, 4))) as biCirImportant
        from
            Param as p
    ),
    ------------------------------------
    -- ビットマップ情報全体
    ------------------------------------
    BitmapInfo as (
        select
            bf.*,
            bi.*,
            (bi.biBitCount/8 * bi.biWidth * bi.biHeight) as PixelCount
        from
            BITMAPFILEHEADER bf,
            BITMAPINFOHEADER bi
    ),
    ------------------------------------
    -- ピクセル数分のシーケンス生成
    ------------------------------------
    Seq(rowIndex, maxRowCount) as (
        select 0, (select PixelCount from BitmapInfo)
        union all
        select
            rowIndex+1, maxRowCount
        from
            Seq
        where
            rowIndex < maxRowCount
    ),
    ------------------------------------
    -- 各ピクセルのRGBを取得
    ------------------------------------
    RawPixels as (
        select
            s.rowIndex as pos,
            round(s.rowIndex / i.biWidth, 0) as row_index,
            s.rowIndex % i.biWidth as col_index,
            1 as alpha,
            dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, i.bfOffBits + (s.rowIndex * 3) + 0, 1)) as red,
            dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, i.bfOffBits + (s.rowIndex * 3) + 1, 1)) as green,
            dbo.Collection_Reverse(dbo.Collection_Range(p.rawdata, i.bfOffBits + (s.rowIndex * 3) + 2, 1)) as blue,
            i.*
        from
            Param as p,
            Seq as s,
            BitmapInfo i
        where
            s.rowIndex < s.maxRowCount / 3
    ),
    ------------------------------------
    -- 固定パラメータ
    ------------------------------------
    BinarizationParam as (
        select 160 as threshold
    ),
    ------------------------------------
    -- 2値化
    ------------------------------------
    Binarization as (
        select
            p.pos,
            p.row_index,
            p.col_index,
            (case
                when p.red < BinarizationParam.threshold then 0
                when p.green < BinarizationParam.threshold then 0
                when p.blue < BinarizationParam.threshold then 0
                else 1
            end) as pix
        from
            RawPixels as p,
            BinarizationParam
    )
insert into
    result_image
select
    *
from
    Binarization

option (maxrecursion 0)


------------------------------------
-- 列名一覧作成
------------------------------------
declare @col_list varchar(max) = ''

select
    @col_list = 
        @col_list +
        (case when len(@col_list) > 0 then ',' + char(13) else '' end) +
        '(case ' +
            'when max(case when col_index = ' + cast(col_index as varchar(max)) + ' then pix else 0 end) = 1 then ' +
                ''''' ' +
            'else ' +
                '''■'' ' +
        'end) as c' + cast(col_index as varchar(max))
from
    result_image
group by
    col_index
order by
    col_index

------------------------------------
-- 出力
------------------------------------
declare @sql varchar(max) =
    'select ' + char(13) +
        'row_index as r,' + char(13) +
        @col_list + char(13) +
    'from ' + char(13) +
        'result_image ' + char(13) +
    'group by row_index ' + char(13) +
    'order by row_index desc'

--print @sql
execute sp_sqlexec @sql

go

2014年8月24日日曜日

グレースケールその2

ループもアセンブラで書いた
void apply_grayscale(uint8_t* dstImg, uint8_t* srcImg, int pixelCount)
{
    uint16_t tmp1;
    int counter;

    __asm
    {
        mov ebx, srcImg
        mov ecx, pixelCount
        mov counter, 0
            
    loop0:
        mov tmp1, 0

        mov ah, 77                        // 0.298912 * 256
        mov al, [ebx+0]
        mul ah
        mov tmp1, ax

        mov ah, 150                        // 0.586611 * 256
        mov al, [ebx+1]
        mul ah
        add tmp1, ax

        mov ah, 29                        // 0.114478 * 256
        mov al, [ebx+2]
        mul ah
        add tmp1, ax
        
        shr tmp1, 8
        mov ax, tmp1

        push ebx
        mov ebx, dstImg
        add ebx, counter
        mov [ebx+0], al
        mov [ebx+1], al
        mov [ebx+2], al
        pop ebx

        add counter, 3
        add ebx, 3
        sub ecx, 3
        jnz loop0
    }
}
もうちょい短くなるのかな?

2014/08/24 18:31 追記
ちょっと短くなった
void apply_grayscale(uint8_t* dstImg, uint8_t* srcImg, int pixelCount)
{
    int counter;

    __asm
    {
        mov ebx, srcImg
        mov ecx, pixelCount
        mov counter, 0
            
    loop0:
        mov dx, 0

        mov ax, 77                        // 0.298912 * 256
        mul [ebx+0]
        mov dx, ax

        mov ax, 150                       // 0.586611 * 256
        mul [ebx+1]
        add dx, ax

        mov ax, 29                        // 0.114478 * 256
        mul [ebx+2]
        add dx, ax
        
        shr dx, 8

        push ebx
        mov ebx, dstImg
        add ebx, counter
        mov [ebx+0], dl
        mov [ebx+1], dl
        mov [ebx+2], dl
        pop ebx

        add counter, 3
        add ebx, 3
        sub ecx, 3
        jnz loop0
    }
}

2014年8月23日土曜日

グレースケール

初めて画像処理をアセンブラで書いてみた
アセンブラでロジックを書くのは初めてかな
#include <cstdint>
#include <fstream>

using namespace std;

int main()
{
    static const int IMG_HEADER_SIZE = 54;
    uint8_t* hdr = new uint8_t[IMG_HEADER_SIZE];
    memset(hdr, 0, IMG_HEADER_SIZE);

    static const int IMG_DATA_SIZE = 1024*768*3; 
    uint8_t* img = new uint8_t[IMG_DATA_SIZE];
    memset(img, 0, IMG_DATA_SIZE);

    ifstream input_file("C:\\Users\\xxxxx\\Desktop\\Desert.bmp", ios::binary);
    input_file.read(reinterpret_cast<char*>(hdr), IMG_HEADER_SIZE);
    input_file.read(reinterpret_cast<char*>(img), IMG_DATA_SIZE);

    for (int i = 0; i < IMG_DATA_SIZE; i+=3)
    {
        static const int GS_R8_WEIGHT = static_cast<int>(0.298912 * 256);
        static const int GS_G8_WEIGHT = static_cast<int>(0.586611 * 256);
        static const int GS_B8_WEIGHT = static_cast<int>(0.114478 * 256);

        uint8_t r8 = img[i+0];
        uint8_t g8 = img[i+1];
        uint8_t b8 = img[i+2];
        uint16_t tmp1;
        uint8_t result;

        __asm
        {
            mov tmp1, 0x00

            mov ah, 0
            mov al, r8
            mul GS_R8_WEIGHT
            mov tmp1, ax

            mov ah, 0
            mov al, g8
            mul GS_G8_WEIGHT
            add tmp1, ax

            mov ah, 0
            mov al, b8
            mul GS_B8_WEIGHT
            add tmp1, ax
        
            shr tmp1, 8
            push tmp1
            pop result
        }

        img[i+0] = result;
        img[i+1] = result;
        img[i+2] = result;
    }

    ofstream output_file("C:\\Users\\xxxxx\\Desktop\\Desert_grayscale.bmp", ios::binary);
    output_file.write(reinterpret_cast<char*>(hdr), IMG_HEADER_SIZE);
    output_file.write(reinterpret_cast<char*>(img), IMG_DATA_SIZE);
    output_file.close();

    delete[] hdr;
    delete[] img;

    return 0;
}

2013年2月12日火曜日

Windowsの特権を操作

久しぶりに特権関連を書いてみた。

stdafx.h
#pragma once

#include "targetver.h"

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

#include <tchar.h>

#include <string>
#include <iostream>
#include <boost/format.hpp>
#include <boost/scoped_array.hpp>

#include <Windows.h>
#include <NTSecAPI.h>


sample.cpp

#include "stdafx.h"

#if defined(UNICODE) || defined(_UNICODE)
#define tstring std::wstring
#define tcout std::wcout
#define tformat boost::wformat
#else
#define tstring std::string
#define tcout std::cout
#define tformat boost::format
#endif

class Privilege
{
private:
    LUID_AND_ATTRIBUTES luidAndAttrs;
    tstring name;
    tstring displayName;

public:
    static const int PRIV_NAME_MAX_LENGTH = 64;
    static const int PRIV_DISPNAME_MAX_LENGTH = 128;
    typedef std::vector<boost::shared_ptr<Privilege>> PrivilegeContainer;

    Privilege(LUID_AND_ATTRIBUTES luidAndAttrs)
    {
        this->luidAndAttrs = luidAndAttrs;
    }

    static PrivilegeContainer GetPrivileges()
    {
        PrivilegeContainer result;
        HANDLE hToken;

        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
        {
            tcout << "OpenProcessToken 失敗" << std::endl;
            return result;
        }

        DWORD length;
        GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &length);
        boost::scoped_array<TOKEN_PRIVILEGES> privs(new TOKEN_PRIVILEGES[length]);
        GetTokenInformation(hToken, TokenPrivileges, privs.get(), length, &length);


        for (DWORD i=0; i<privs.get()->PrivilegeCount; i++)
        {
            auto luidAndAttrs = privs.get()->Privileges[i];
            boost::shared_ptr<Privilege> priv(new Privilege(luidAndAttrs));
            result.push_back(priv);
        }

        CloseHandle(hToken);

        return result;
    }

    tstring GetName()
    {
        if (this->name.empty())
        {
            DWORD cchName = PRIV_NAME_MAX_LENGTH;
            TCHAR name[PRIV_NAME_MAX_LENGTH+1] = {0};

            LookupPrivilegeName(NULL, &this->luidAndAttrs.Luid, name, &cchName);
            this->name = tstring(name);
        }
        return this->name;
    }

    tstring GetDisplayName()
    {
        if (this->displayName.empty())
        {
            DWORD cchDispName = PRIV_DISPNAME_MAX_LENGTH;
            TCHAR dispname[PRIV_DISPNAME_MAX_LENGTH+1] = {0};
            DWORD langID = 0;

            LookupPrivilegeDisplayName(NULL, GetName().c_str(), dispname, &cchDispName, &langID);
            this->displayName = tstring(dispname);
        }
        return this->displayName;
    }

    DWORD GetStatus() const
    {
        return this->luidAndAttrs.Attributes;
    }

    tstring GetStatusText() const
    {
        tstring text;
        if (this->luidAndAttrs.Attributes & SE_PRIVILEGE_ENABLED)
        {
            text.append(_T("有効"));
        }
        else
        {
            text.append(_T("無効"));
        }
        return text;
    }

    void SetStatus(DWORD status)
    {
        HANDLE hToken;

        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
        {
            tcout << "OpenProcessToken 失敗" << std::endl;
            return;
        }
        TOKEN_PRIVILEGES privs;
        privs.PrivilegeCount = 1;
        privs.Privileges[0].Attributes = status;
        privs.Privileges[0].Luid = this->luidAndAttrs.Luid;
        if (!AdjustTokenPrivileges(hToken, FALSE, &privs, 0, NULL, NULL))
        {
            tcout << "AdjustTokenPrivileges 失敗" << std::endl;
            CloseHandle(hToken);
            return;
        }

        this->luidAndAttrs.Attributes = status;
        CloseHandle(hToken);
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    _tsetlocale(LC_ALL, _T(""));

    tcout << _T("----- before -----") << std::endl;

    auto privs = Privilege::GetPrivileges();
    for each(auto priv in privs)
    {
        auto ptr = priv.get();
        tcout
            << tformat(L"%-4s %-64s %-128s") 
                % ptr->GetStatusText()
                % ptr->GetName()
                % ptr->GetDisplayName()
            << std::endl;
    }

    tcout << _T("----- 特権操作 -----") << std::endl;

    auto pred = 
        [](const boost::shared_ptr<Privilege> &p) {
            return (p->GetName() == SE_SHUTDOWN_NAME);
        };
    auto targetPriv = std::find_if(privs.begin(), privs.end(), pred);
    tcout << targetPriv->get()->GetName() << std::endl;
    targetPriv->get()->SetStatus(SE_PRIVILEGE_ENABLED);

    tcout << _T("----- after -----") << std::endl;

    privs = Privilege::GetPrivileges();
    for each(auto priv in privs)
    {
        auto ptr = priv.get();
        tcout
            << tformat(L"%-4s %-64s %-128s") 
                % ptr->GetStatusText()
                % ptr->GetName()
                % ptr->GetDisplayName()
            << std::endl;
    }

    return EXIT_SUCCESS;
}

2012年11月24日土曜日

自分のテーブルデータを一括削除

とりあえず、単純なものを。メモっとかないと忘れてしまう・・・
use [DB]
go

declare cur_user_tables cursor for
select
  all_obj.name
from
  sys.all_objects as all_obj
  inner join sys.schemas s on
    s.name = 'dbo' and
    s.schema_id = all_obj.schema_id
where
  all_obj.type = 'U' and
  all_obj.is_ms_shipped = 0
;

declare @table_name varchar(max)
declare @sql varchar(max)

open cur_user_tables;

fetch next from cur_user_tables
  into @table_name;

while @@FETCH_STATUS = 0
begin
  set @sql = 'delete from ' + @table_name;
  print @sql
  execute(@sql)

  fetch next from cur_user_tables
    into @table_name;
end

close cur_user_tables;
deallocate cur_user_tables;

go

2012年9月9日日曜日

adbで一括pull

AndroidからWindowsへ、対象ファイルを一括コピーしたい時は超便利!
PowerShell使って楽してみた。
ls結果をforeachで回した時に、空文字列が交互に存在したからwhereで省いた。
adb shell "ls /mnt/sdcard/Pictures/*jpg" | ?{ $_.Length -gt 0 } | %{ adb pull $_ ("d:\tmp\" + [IO.Path]::GetFileName($_)) }

2012年8月27日月曜日

無効ボタン画像生成

アプリ作ってると画像のリソースが必要になる。ボタンだと、 enable, disable, mouse over, click などの状態別に必要・・・って結構めんどくさい。手を抜きたい。
enableを用意したら、他はPowerShell + ImageMagick で楽に作る。
色の事はよく分かんないから、輝度と彩度をいじっただけ。
ls |
  %{
    $name = [IO.Path]::GetFileNameWithoutExtension($_.Name)
    $ext = [IO.Path]::GetExtension($_.Name)
    $disable_name = $name + "_disable" + $ext
    $over_name = $name + "_over" + $ext
    
    convert $_.Name -modulate "100,0,100" $disable_name
    convert $_.Name -modulate "150,100,100" $over_name
  }
どっかで mogrify 使って 一括変換出来るって書いてあったけど、そのコードが動かないから結局ループ(;_;)

2012年8月26日日曜日

Windows 8 Release Preview に、Wiresharkをインストールしてみた。
WinPcapインストール時に、Windowsの互換性に問題あるとかで一旦失敗したけど、
「互換モード」を Windows XP SP3 に設定したらインストールできた。
(Windows 7 でも出来ると思う)

2012年8月25日土曜日

SQLでINSERT文を生成

SQLでinsert文を生成してみた!おまけでcreate文(中途半端)も。
テストデータはinsert文じゃないと嫌な人は、これに手を加えて再利用できるかも?

クエリ

with
  param as (
    select
      'SAKURAGI' as owner,
      'EMP' as table_name
    from
      dual
  ),
  seq as (
    select
      rownum as value
    from
      dual
    connect by
      rownum <= 5
  ),
  data as (
    select
      s.value,
      tc.table_name,
      tc.column_id,
      tc.column_name,
      tc.data_type,
      tc.nullable,
      case
        when tc.data_type = any('CHAR', 'VARCHAR2') then
          tc.data_type || '(' || tc.char_length || ')'
        when tc.data_type = 'NUMBER' then
          tc.data_type || '(' || tc.data_length || ',' || nvl(tc.data_scale, 0) || ')'
        else
          tc.data_type
      end as data_type_text,
      case
        when tc.data_type = any('CHAR', 'VARCHAR2') then
          lpad(s.value, tc.char_length, '0')
        when tc.data_type = 'DATE' then
          'to_date(''' || to_char(sysdate+s.value, 'yyyy-mm-dd HH24:mi:ss') || ''', ''yyyy-mm-dd HH24:mi:ss'')'
        else
          rtrim(to_char(s.value) || '.' || lpad(s.value, tc.data_scale, '0'), '.')
      end as sample_value
    from
      all_tab_cols tc,
      seq s,
      param
    where
      tc.owner = param.owner and
      tc.table_name = param.table_name
    order by
      tc.column_id
  ),
  formatted_data as (
    select
      d.*,
      case
        when d.data_type = any('CHAR', 'VARCHAR2') then
          '''' || d.sample_value || ''''
        else
          d.sample_value
      end as formatted_value
    from
      data d
    order by
      d.column_id
  ),
  idx_info as (
    select
      col.column_id,
      col.table_name,
      col.column_name,
      ind_col.index_name,
      cons.constraint_name,
      cons.constraint_type
    from
      user_tab_cols col
      inner join user_ind_columns ind_col on
        ind_col.table_name = col.table_name and
        ind_col.column_name = col.column_name
      inner join user_constraints cons on
        cons.table_name = ind_col.table_name and
        cons.index_name = ind_col.index_name,
      param
    where
      col.table_name = param.table_name
  ),
  create_parts as (
    select
      d.table_name,
      listagg(
        d.column_name || ' ' ||
          d.data_type_text ||
          (case when d.nullable = 'N' then ' not null' end),
        ', '
      ) within group (order by d.column_id) as column_list
    from
      data d
    where
      d.value = 1
    group by
      d.table_name
  ),
  insert_parts as (
    select
      d.value,
      d.table_name,
      ----- case 1 -----
      --rtrim(regexp_replace(xmlagg(xmlelement(TAG,d.column_name||',') order by d.column_id), '', ''), ',') as column_list,
      --replace(rtrim(regexp_replace(xmlagg(xmlelement(TAG,d.formatted_value||',') order by d.column_id), '', ''), ','), chr(38)||'apos;', '''') as value_list
      ----- case 2 -----
      listagg(d.column_name, ', ') within group (order by d.column_id) as column_list,
      listagg(d.formatted_value, ', ') within group (order by d.column_id) as value_list
    from
      formatted_data d
    group by
      d.value,
      d.table_name
  )
select
  'create table ' || p.table_name || ' (' || p.column_list ||
    (case when idx.column_list is not null then (', primary key(' || idx.column_list || ')') end) || ');' as query
from
  create_parts p
  left outer join (
    select
      idx.table_name,
      listagg(idx.column_name, ', ') within group (order by idx.column_id) as column_list
    from
      idx_info idx
    group by
      idx.table_name
  ) idx on idx.table_name = p.table_name
union all
select
  'insert into ' || p.table_name || ' (' || p.column_list || ')' || ' values (' || p.value_list || ');' as query
from
  insert_parts p
;

実行結果

create table EMP (EMPNO NUMBER(22,0) not null, ENAME VARCHAR2(10), JOB VARCHAR2(9), MGR NUMBER(22,0), HIREDATE DATE, SAL NUMBER(22,2), COMM NUMBER(22,2), DEPTNO NUMBER(22,0), primary key(EMPNO));
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (1, '0000000001', '000000001', 1, to_date('2012-08-26 16:07:22', 'yyyy-mm-dd HH24:mi:ss'), 1.01, 1.01, 1);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (2, '0000000002', '000000002', 2, to_date('2012-08-27 16:07:22', 'yyyy-mm-dd HH24:mi:ss'), 2.02, 2.02, 2);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (3, '0000000003', '000000003', 3, to_date('2012-08-28 16:07:22', 'yyyy-mm-dd HH24:mi:ss'), 3.03, 3.03, 3);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (4, '0000000004', '000000004', 4, to_date('2012-08-29 16:07:22', 'yyyy-mm-dd HH24:mi:ss'), 4.04, 4.04, 4);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (5, '0000000005', '000000005', 5, to_date('2012-08-30 16:07:22', 'yyyy-mm-dd HH24:mi:ss'), 5.05, 5.05, 5);

2012年8月21日火曜日

SQLで素因数分解

素因数分解やってみた。
with
    target as (
        select
            4294967295 value,
            2 as prime
        from
            dual
    ),
    prime_factorization (value, prime, success) as (
        select
            value,
            prime,
            null
        from
            target
        union all
        select
            case
                when mod(value, prime) = 0 then value/prime
                else value
            end,
            case
                when mod(value, prime) = 0 then prime
                else prime + 1
            end,
            case
                when mod(value, prime) = 0 then 1
                else 0
            end
        from
            prime_factorization
        where
            value > 1 or (value = prime)
    )
select
    ((select value from target) ||
     ' = ' ||
     listagg(prime, ' * ') within group (order by prime)
    ) as result
from
    prime_factorization
where
    success = 1
group by
    null

SQLで全加算器

何か奇抜な事をしてみたくて思いついたのが、SQLで全加算器の真理値表を作る事。
with
    data (input1, input2) as (
        select 0, 0 from dual union all
        select 0, 1 from dual union all
        select 1, 0 from dual union all
        select 1, 1 from dual
    ),
    data2 as (
        select
            utl_raw.cast_from_binary_integer(input1) as input1,
            utl_raw.cast_from_binary_integer(input2) as input2
        from
            data
    ),
    -- 半加算器
    half_adder as (
        select
            input1,
            input2,
            utl_raw.bit_or(
                utl_raw.bit_and(
                    input1,
                    utl_raw.bit_complement(input2)
                ),
                utl_raw.bit_and(
                    utl_raw.bit_complement(input1),
                    input2
                )
            ) as output_sum,
            utl_raw.bit_and(input1, input2) as output_carry
        from
            data2
    ),
    -- 全加算器
    full_adder as (
        select
            ha1.input1 as a,
            ha1.input2 as b,
            ha2.input2 as x,
            utl_raw.bit_or(
                ha1.output_carry,
                ha2.output_carry
            ) as c,
            ha2.output_sum as s
        from
            half_adder ha1
            inner join half_adder ha2 on
                ha1.output_sum = ha2.input1
    )
select
    to_number(fa.a) as a,
    to_number(fa.b) as b,
    to_number(fa.x) as x,
    to_number(fa.c) as c,
    to_number(fa.s) as s
from
    full_adder fa
order by
    fa.a || fa.b || fa.x

SQLでFizzBuzz

SQLでFizzBuzzをやってみた。
select
    rownum as num,
    nvl(
        case when mod(rownum, 3) = 0 then 'Fizz' end ||
            case when mod(rownum, 5) = 0 then 'Buzz' end,
        rownum
    ) as val
from
    dual
connect by
    rownum <= 100

SQLで正弦波

SQLで正弦波を描いてみました。
with
    data as (
        select
            rownum as num,
            trunc(amp * sin((rownum-1)/180 * 3.14 * freq) * 10) + 50 as pos
        from
            (select 1.5 as amp, 20 as freq from dual)
        connect by
            rownum <= 1000
    )
 
select
    lpad(' ', d.pos) || '*' || lpad(' ', d.pos) as plot
from
    data d

FC2からBloggerに移行

sakuragi's blog からの完全移行がめんどい・・・

SQL で MP4 をパース

SQL でビットマップ画像の2値化は4年位前に挑戦した。 最近、それの Impala 版 を作ったときに閃いた。 「再帰CTEがあるなら、mp4 もいけるんじゃないか」と。 やってみた。 use ragingo drop table video go create...