⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 viewer.cpp

📁 这是一个JPEG解码器,里面使用了MMX,SSE等汇编指令集
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            deltaY = pos;
            img.scrollY = si.nPos;
        }
        else
        {
            deltaX = pos;
            img.scrollX = si.nPos;
        }
        GetClientRect(wnd.hwnd, &rect);
        rect.bottom -= wnd.statusHeight;
        img.srcX = img.scrollX;
        img.srcY = img.scrollY;
        ScrollWindowEx(hwnd, deltaX, deltaY, &rect, &rect, NULL, NULL, SW_INVALIDATE);
        UpdateWindow(hwnd);
    }
    
    return 0;
}

// set image position
void setImagePos(int screenWidth, int screenHeight)
{    
    SCROLLINFO scroll;
    UINT wArrows;

    img.dstX = max((screenWidth - img.width) / 2, 0);
    img.dstY = max((screenHeight - img.height) / 2, 0);
    img.dstWidth = min(screenWidth, img.width);
    img.dstHeight = min(screenHeight, img.height);
    if (img.scrollX + img.dstWidth >= img.width)
        img.scrollX = img.width - img.dstWidth;
    if (img.scrollY + img.dstHeight >= img.height)
        img.scrollY = img.height - img.dstHeight;
    img.srcX = img.scrollX;
    img.srcY = img.scrollY;

    if (img.width <= screenWidth && img.height <= screenHeight)
    {
        ShowScrollBar(wnd.hwnd, SB_BOTH, FALSE);
    }
    else
    {
        scroll.cbSize = sizeof(scroll);
        scroll.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
        scroll.nMin = 0;
        wArrows = ESB_DISABLE_BOTH;
        if (img.width > screenWidth)
        {
            scroll.nMax = img.width;
            scroll.nPage = screenWidth;
            scroll.nPos = img.scrollX;
            SetScrollInfo(wnd.hwnd, SB_HORZ, &scroll, TRUE);
            wArrows = ESB_ENABLE_BOTH;
        }
        EnableScrollBar(wnd.hwnd, SB_HORZ, wArrows);
        wArrows = ESB_DISABLE_BOTH;
        if (img.height > screenHeight)
        {
            scroll.nMax = img.height;
            scroll.nPage = screenHeight;
            scroll.nPos = img.scrollY;
            SetScrollInfo(wnd.hwnd, SB_VERT, &scroll, TRUE);
            wArrows = ESB_ENABLE_BOTH;
        }
        EnableScrollBar(wnd.hwnd, SB_VERT, wArrows);
    }
}

// OnCommand
LRESULT OnCommand(HWND hwnd, WORD menuId, LPARAM lParam)
{
    switch (menuId)
    {
        case ID_FILE_OPEN40001:
            OnFileOpen();
        break;

        case ID_FILE_CLOSE40002:
            OnFileClose();
        break;

        case ID_FILE_QUIT:
            OnFileQuit();
        break;
    }

    return 0;
}

// File->Open
void OnFileOpen(void)
{
#define MAX_FILE_NAME 256
    char filename[MAX_FILE_NAME];
    OPENFILENAME ofn;
    
    ZeroMemory(&ofn, sizeof(ofn));

    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = wnd.hwnd;
    ofn.lpstrFilter = "JPEG files\0*.jpg\0All files\0*.*\0\0\0";
    ofn.lpstrFile = & filename[0];
    filename[0] = 0;
    ofn.nMaxFile = sizeof(filename);
    ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
    if (GetOpenFileName(&ofn))
    {
        if (readFile(filename))
        {
            SetWindowText(wnd.hwnd, &filename[ofn.nFileOffset]);
        }
    }
    else
    {
        if (CommDlgExtendedError())
        {
            MessageBox(wnd.hwnd, "Cannot create window to open file", "Error", MB_OK);
        }
    }
}

// File->Close
BOOL OnFileClose(void)
{
    freeBitmap();
    menuChange(0, MENU_CLOSE);
    SetWindowText(wnd.hwnd, WINDOW_TITLE);
    SetWindowText(wnd.status, STATUS_INIT);
    ShowScrollBar(wnd.hwnd, SB_BOTH, FALSE);
    ZeroMemory(&img, sizeof(img));
    InvalidateRect(wnd.hwnd, NULL, TRUE);

    return TRUE;
}

// File->Quit
void OnFileQuit(void)
{
    OnDestroy();
}

// read file in a buffer
BOOL readFile(char* filename)
{
    BOOL ret = FALSE;
    HANDLE hfile;
    BY_HANDLE_FILE_INFORMATION fileinfo;
    char* buffer = NULL;
    unsigned nbread;

    hfile = CreateFile(filename, GENERIC_READ, 
                        FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hfile != INVALID_HANDLE_VALUE)
    {
        if (GetFileInformationByHandle(hfile, &fileinfo))
        {
            if (fileinfo.nFileSizeHigh == 0)
            {
                buffer = (char*) allocMem(fileinfo.nFileSizeLow);
                if (buffer)
                {
                    if (ReadFile(hfile, buffer, fileinfo.nFileSizeLow, &nbread, NULL))
                    {
                        if (nbread == fileinfo.nFileSizeLow)
                        {
                            ret = newFileOpened(buffer, nbread);
                        }
                    }
                    freeMem(buffer);
                }
            }
        }

        CloseHandle(hfile);
    }

    return ret;
}

// allocate memory
void* allocMem(int size)
{
    return HeapAlloc(GetProcessHeap(), 0, size);
}

// free memory
void freeMem(void* mem)
{
    HeapFree(GetProcessHeap(), 0, mem);
}

// new file opened
BOOL newFileOpened(char* buffer, int size)
{
    BOOL ret = FALSE;
    int code = JPEG_FORMATNOTSUPPORTED;
    JPEGIMAGE* jimg;
    HDC cdc, wdc;
    BITMAPINFO bmi;
    BITMAPINFOHEADER* bmhdr;
    HBITMAP cbm, oldbm;
    unsigned time;
    RECT rect;

    // decode the buffer
    time = GetTickCount();
    code = JPEG_Decode(buffer, size, &jimg, 0);
    time = GetTickCount() - time;
    
    if (code == JPEG_SUCCESS)
    {        
        // copy the image in a dc
        wdc = GetDC(wnd.hwnd);
        if (wdc)
        {
            cdc = CreateCompatibleDC(wdc);
            if (cdc)
            {
                cbm = CreateCompatibleBitmap(wdc, jimg->width, jimg->height);
                if (cbm)
                {
                    bmhdr = & bmi.bmiHeader;
                    bmhdr->biSize = sizeof(*bmhdr);
                    bmhdr->biWidth = jimg->scanlength;
                    bmhdr->biHeight = - (int)jimg->height;
                    bmhdr->biPlanes = 1;
                    bmhdr->biBitCount = jimg->bitsPixel;
                    bmhdr->biCompression = BI_RGB;
                    if (SetDIBits(cdc, cbm, 0,
                                    jimg->height, jimg->pRGB, &bmi,
                                    DIB_RGB_COLORS) == jimg->height)
                    {
                        oldbm = (HBITMAP) SelectObject(cdc, cbm);
                        if (oldbm)
                        {
                            // free previous resource
                            OnFileClose();
                            img.oldbm = oldbm;
                            img.dc = cdc;
                            img.width = jimg->width;
                            img.height = jimg->height;
                            menuChange(MENU_CLOSE, 0);
                            setStatusInfo(time, jimg);
                            GetClientRect(wnd.hwnd, &rect);
                            setImagePos(rect.right, rect.bottom - wnd.statusHeight);
                            InvalidateRect(wnd.hwnd, NULL, TRUE);
                            ret = TRUE;
                        }
                    }
                }
            }
            ReleaseDC(wnd.hwnd, wdc);
        }
        // free the image
        JPEG_Free(jimg);
    }

    if (ret == FALSE)
    {
        if (code != JPEG_SUCCESS)
        {
            displayError(code);
        }
        else
        {
            MessageBox(wnd.hwnd, "Error", "can't allocate graphics object", MB_OK);
        }
    }

    return ret;
}

// free bitmap
void freeBitmap(void)
{
    HBITMAP hbm;
    if (img.dc)
    {
        hbm = (HBITMAP) SelectObject(img.dc, img.oldbm);
        if (hbm)
        {
            DeleteObject(hbm);
        }
        DeleteDC(img.dc);
        img.width = img.height = 0;
        img.dc = NULL;
    }    
}

// change menu
void menuChange(unsigned set, unsigned reset)
{
    UINT id;
    unsigned val[2];
    unsigned flags;
    unsigned i;
    UINT state;
    HMENU hmenu = GetMenu(wnd.hwnd);

    val[0] = set;
    val[1] = reset;
       
    if (hmenu)
    {
        state = MF_ENABLED;
        for (i = 0; i < 2; i++)
        {
            id = FIRST_MENU_ID;
            flags = val[i];
            while (flags)
            {
                if (flags & 1)
                {
                    EnableMenuItem(hmenu, id, state);
                }
                id++;
                flags >>= 1;
            }
            state = MF_GRAYED;
        }
    }
}

// set status info
void setStatusInfo(unsigned time, JPEGIMAGE* img)
{
    char buffer[256];
    int nb;
    char* str;
    if (time)
        str = "%dx%d - %s - %d bpp - %d ms";
    else
        str = "%dx%d - %s - %d bpp - < 1 ms";
    nb = wsprintf(buffer, str, img->width, img->width,
                  img->Nf == 1 ? "Grayscale" : "Color", img->bitsPixel, time);
    buffer[nb] = 0;
    SetWindowText(wnd.status, buffer);
}

// display error message
void displayError(int code)
{
    char* msg;
    
    switch (code)
    {
        case JPEG_EOF:
            msg = "unexpected end of file";
        break;
        case JPEG_OUTOFMEM:
            msg = "out of memory";
        break;
        case JPEG_CPUNOTSUPPORTED:
            msg = "cpu not supported";
        break;
        case JPEG_BADFILE:
            msg = "bad file";
        break;        
        case JPEG_FORMATNOTSUPPORTED:
            msg = "format not supported";
        break;
        default:
            msg = "unknown error code";
        break;
    }

    MessageBox(wnd.hwnd, msg, "Error", MB_OK);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -