function Xf=compressimquant(imagename,color,crop,p,quant)
    % read image
    im = imread(imagename);
    % perform color alterations to image
    % note: imgray will not always be grayscale
    if strcmp(color,'gray')
        imgray = rgbim2gray(im);
    elseif strcmp(color,'rgb')
        imgray = double(im);
    elseif strcmp(color,'yuv')
        imgray = rgbim2luminance(im);
    end
    % obtain original dimensions to handle non-square images
    origrows = size(imgray,1);
    origcols = size(imgray,2);
    % pre-allocate imgraysq for speed using inputs
    if crop && (strcmp(color,'rgb') || strcmp(color,'yuv'))
        sqrows = min(origrows,origcols);
        imgraysq = zeros(sqrows,sqrows,3);
    elseif ~crop && (strcmp(color,'rgb') || strcmp(color,'yuv'))
        targetrows = 8*(round(origrows/8));
        targetcols = 8*(round(origcols/8));
        targetrows = max(targetrows,targetcols);
        imgraysq = zeros(targetrows,targetrows,3);
    elseif crop && strcmp(color,'gray')
        sqrows = min(origrows,origcols);
        imgraysq = zeros(sqrows,sqrows,1);
    elseif ~crop && strcmp(color,'gray')
        targetrows = 8*(round(origrows/8));
        targetcols = 8*(round(origcols/8));
        targetrows = max(targetrows,targetcols);
        imgraysq = zeros(targetrows,targetrows,1);
    end
    % prep square matrix for transformation
    for rgb=1:size(imgray,3)
        imgraysq(:,:,rgb) = tosquare(imgray(:,:,rgb),8,crop);
    end
    % if not using yuv: center pixel values
    if ~strcmp(color,'yuv')
        xc = imgraysq-128;
    else
        xc = imgraysq;
    end
    % compress by 8x8 blocks
    Xdq = zeros(size(xc,1),size(xc,2),size(xc,3));
    C=dctMat(8);
    if strcmp(quant,'lin')
        Qy=p*8./hilb(8); % linear quantization
        Qc=Qy;
    % build quantization matrices
    elseif strcmp(quant,'jpeg') && (strcmp(color,'rgb') || strcmp(color,'gray'))
        Qy=p*[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];
        Qc=Qy;
    elseif strcmp(quant,'jpeg') && strcmp(color,'yuv')
        Qy=p*[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];
        
        Qc=p*[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];
    end
    % Apply transform
    for rgb=1:size(xc,3)
        for boxrow=1:8:size(xc,1)
            for boxcol=1:8:size(xc,2)
                % if statement necessary for yuv implementation but works
                %   for grayscale and rgb
                if rgb==1
                    ybox=twoDimDCT(xc(boxrow:(boxrow+7),boxcol:(boxcol+7),rgb),C);
                    yboxq=round(ybox./Qy);
                    yboxdq=yboxq.*Qy;
                    Xdq(boxrow:(boxrow+7),boxcol:(boxcol+7),rgb)=invertTwoDimDCT(yboxdq,C);
                else
                    ybox=twoDimDCT(xc(boxrow:(boxrow+7),boxcol:(boxcol+7),rgb),C);
                    yboxq=round(ybox./Qc);
                    yboxdq=yboxq.*Qc;
                    Xdq(boxrow:(boxrow+7),boxcol:(boxcol+7),rgb)=invertTwoDimDCT(yboxdq,C);
                end
            end
        end
    end
    % if using yuv: convert back to rgb
    if strcmp(color,'yuv')
        Xdq=lum2rgb(Xdq);
    end
    % if not using yuv: de-center pixels
    if ~strcmp(color,'yuv')
        Xe=Xdq+128;
    else
        Xe=Xdq;
    end
    Xf=uint8(Xe(1:origrows,1:origcols,:));
%     yboxq;